text:
//******************************************************************************
// RCF - Remote Call Framework
//
// Copyright (c) 2005 - 2013, Delta V Software. All rights reserved.
// http://www.deltavsoft.com
//
// RCF is distributed under dual licenses - closed source or GPL.
// Consult your particular license for conditions of use.
//
// If you have not purchased a commercial license, you are using RCF
// under GPL terms.
//
// Version: 2.0
// Contact: support <at> deltavsoft.com
//
//******************************************************************************

#include "TransportFactories.hpp"

#include <iostream>
#include <typeinfo>
#include <utility>
#include <vector>

#include <sys/stat.h>

#include <boost/config.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/version.hpp>

#include <RCF/ClientStub.hpp>
#include <RCF/InitDeinit.hpp>
#include <RCF/ThreadLibrary.hpp>

#include <RCF/TcpServerTransport.hpp>
#include <RCF/Asio.hpp>
#include <RCF/Config.hpp>

#ifdef RCF_HAS_LOCAL_SOCKETS
#include <RCF/UnixLocalClientTransport.hpp>
#include <RCF/UnixLocalServerTransport.hpp>
#endif

#if RCF_FEATURE_NAMEDPIPE==1
#include <RCF/Win32NamedPipeClientTransport.hpp>
#include <RCF/Win32NamedPipeEndpoint.hpp>
#include <RCF/Win32NamedPipeServerTransport.hpp>
#endif

#if RCF_FEATURE_HTTP==1
#include <RCF/HttpClientTransport.hpp>
#include <RCF/HttpServerTransport.hpp>
#include <RCF/HttpEndpoint.hpp>

#include <RCF/HttpsClientTransport.hpp>
#include <RCF/HttpsServerTransport.hpp>
#include <RCF/HttpsEndpoint.hpp>
#endif

#include <RCF/TcpClientTransport.hpp>
#include <RCF/UdpClientTransport.hpp>
#include <RCF/UdpServerTransport.hpp>

#include <RCF/ObjectFactoryService.hpp>

namespace RCF {

    TransportFactories &getTransportFactories()
    {
        static TransportFactories transportFactories;
        return transportFactories;
    }

    TransportFactories &getIpTransportFactories()
    {
        static TransportFactories ipTransportFactories;
        return ipTransportFactories;
    }

    //**************************************************
    // transport factories

    static std::string loopBackV4 = "127.0.0.1";
    static std::string loopBackV6 = "::1";

#if RCF_FEATURE_NAMEDPIPE==1

    TransportPair Win32NamedPipeTransportFactory::createTransports()
    {
        typedef boost::shared_ptr<Win32NamedPipeServerTransport> Win32NamedPipeServerTransportPtr;
        Win32NamedPipeServerTransportPtr serverTransportPtr(
            new Win32NamedPipeServerTransport(RCF_T("")));

        tstring pipeName = serverTransportPtr->getPipeName();

        ClientTransportAutoPtrPtr clientTransportAutoPtrPtr(
            new ClientTransportAutoPtr(
                new Win32NamedPipeClientTransport(pipeName)));

        return std::make_pair(
            ServerTransportPtr(serverTransportPtr),
            clientTransportAutoPtrPtr);

    }

    TransportPair Win32NamedPipeTransportFactory::createNonListeningTransports()
    {
        return std::make_pair(
            ServerTransportPtr( new Win32NamedPipeServerTransport( RCF_T("")) ),
            ClientTransportAutoPtrPtr());

    }

    bool Win32NamedPipeTransportFactory::isConnectionOriented()
    {
        return true;
    }

    bool Win32NamedPipeTransportFactory::supportsTransportFilters()
    {
        return true;
    }

    std::string Win32NamedPipeTransportFactory::desc()
    {
        return "Win32NamedPipeTransportFactory";
    }

#endif

#if RCF_FEATURE_TCP==1

    TcpTransportFactory::TcpTransportFactory(IpAddress::Type type)
    {
        switch (type)
        {
        case IpAddress::V4: mLoopback = loopBackV4; break;
        case IpAddress::V6: mLoopback = loopBackV6; break;
        default: RCF_ASSERT(0);
        }
    }

    TransportPair TcpTransportFactory::createTransports()
    {
        typedef boost::shared_ptr<TcpServerTransport> TcpServerTransportPtr;
        TcpServerTransportPtr tcpServerTransportPtr(
            new TcpServerTransport( IpAddress(mLoopback, 0)));

        tcpServerTransportPtr->open();
        int port = tcpServerTransportPtr->getPort();

        ClientTransportAutoPtrPtr clientTransportAutoPtrPtr(
            new ClientTransportAutoPtr(
                new TcpClientTransport( IpAddress(mLoopback, port))));

        return std::make_pair(
            ServerTransportPtr(tcpServerTransportPtr),
            clientTransportAutoPtrPtr);
    }

    TransportPair TcpTransportFactory::createNonListeningTransports()
    {
        return std::make_pair(
            ServerTransportPtr( new TcpServerTransport( IpAddress(mLoopback, 0)) ),
            ClientTransportAutoPtrPtr());
    }

    bool TcpTransportFactory::isConnectionOriented()
    {
        return true;
    }

    bool TcpTransportFactory::supportsTransportFilters()
    {
        return true;
    }

    std::string TcpTransportFactory::desc()
    {
        return "TcpTransportFactory (" + mLoopback + ")";
    }

#endif

#if RCF_FEATURE_HTTP==1

    HttpTransportFactory::HttpTransportFactory()
    {
        mLoopback = loopBackV4;
    }

    TransportPair HttpTransportFactory::createTransports()
    {
        typedef boost::shared_ptr<HttpServerTransport> HttpServerTransportPtr;
        HttpServerTransportPtr serverTransportPtr(
            new HttpServerTransport( HttpEndpoint(mLoopback, 0)));

        serverTransportPtr->open();
        int port = serverTransportPtr->getPort();

        ClientTransportAutoPtrPtr clientTransportAutoPtrPtr( new ClientTransportAutoPtr(
                new HttpClientTransport(HttpEndpoint(mLoopback, port))));

        return std::make_pair(
            ServerTransportPtr(serverTransportPtr),
            clientTransportAutoPtrPtr);
    }

    TransportPair HttpTransportFactory::createNonListeningTransports()
    {
        return std::make_pair(
            ServerTransportPtr(new HttpServerTransport( HttpEndpoint(mLoopback, 0))),
            ClientTransportAutoPtrPtr());
    }

    bool HttpTransportFactory::isConnectionOriented()
    {
        return true;
    }

    bool HttpTransportFactory::supportsTransportFilters()
    {
        return true;
    }

    std::string HttpTransportFactory::desc()
    {
        return "HttpTransportFactory (" + mLoopback + ")";
    }

    HttpsTransportFactory::HttpsTransportFactory()
    {
        mLoopback = loopBackV4;
    }

    TransportPair HttpsTransportFactory::createTransports()
    {
        typedef boost::shared_ptr<HttpServerTransport> HttpServerTransportPtr;
        HttpServerTransportPtr serverTransportPtr(
            new HttpServerTransport(HttpEndpoint(mLoopback, 0)));

        serverTransportPtr->open();
        int port = serverTransportPtr->getPort();

        ClientTransportAutoPtrPtr clientTransportAutoPtrPtr(new ClientTransportAutoPtr(
            new HttpClientTransport(HttpEndpoint(mLoopback, port))));

        return std::make_pair(
            ServerTransportPtr(serverTransportPtr),
            clientTransportAutoPtrPtr);
    }

    TransportPair HttpsTransportFactory::createNonListeningTransports()
    {
        return std::make_pair(
            ServerTransportPtr(new HttpServerTransport(HttpEndpoint(mLoopback, 0))),
            ClientTransportAutoPtrPtr());
    }

    bool HttpsTransportFactory::isConnectionOriented()
    {
        return true;
    }

    bool HttpsTransportFactory::supportsTransportFilters()
    {
        return true;
    }

    std::string HttpsTransportFactory::desc()
    {
        return "HttpsTransportFactory (" + mLoopback + ")";
    }

#endif

#if RCF_FEATURE_LOCALSOCKET==1

    UnixLocalTransportFactory::UnixLocalTransportFactory() : mIndex(0)
    {
    }

    TransportPair UnixLocalTransportFactory::createTransports()
    {
        std::string pipeName = generateNewPipeName();

        RCF_LOG_2()(pipeName) << "Creating unix local socket transport pair";

        return std::make_pair(
            ServerTransportPtr( new UnixLocalServerTransport(pipeName) ),
            ClientTransportAutoPtrPtr(
                new ClientTransportAutoPtr(
                    new UnixLocalClientTransport(pipeName))));
    }

    TransportPair UnixLocalTransportFactory::createNonListeningTransports()
    {
        return std::make_pair(
            ServerTransportPtr( new UnixLocalServerTransport("") ),
            ClientTransportAutoPtrPtr());
    }

    bool UnixLocalTransportFactory::isConnectionOriented()
    {
        return true;
    }

    bool UnixLocalTransportFactory::supportsTransportFilters()
    {
        return true;
    }

    bool UnixLocalTransportFactory::fileExists(const std::string & path)
    {
        struct stat stFileInfo = {};
        int ret = stat(path.c_str(), &stFileInfo);
        return ret == 0;
    }

    std::string UnixLocalTransportFactory::generateNewPipeName()
    {
        std::string tempDir = RCF::getRelativeTestDataPath();

        std::string candidate;

        while (candidate.empty() || fileExists(candidate))
        {
            std::ostringstream os;
            os
                << tempDir
                << "TestPipe_"
                << ++mIndex;

            candidate = os.str();
        }

        return candidate;
    }

    std::string UnixLocalTransportFactory::desc()
    {
        return "UnixLocalTransportFactory";
    }

    int mIndex;

#endif // RCF_HAS_LOCAL_SOCKETS

#if RCF_FEATURE_UDP==1

    UdpTransportFactory::UdpTransportFactory(IpAddress::Type type)
    {
        switch (type)
        {
        case IpAddress::V4: mLoopback = loopBackV4; break;
        case IpAddress::V6: mLoopback = loopBackV6; break;
        default: RCF_ASSERT(0);
        }
    }

    TransportPair UdpTransportFactory::createTransports()
    {
        typedef boost::shared_ptr<UdpServerTransport> UdpServerTransportPtr;
        UdpServerTransportPtr udpServerTransportPtr(
            new UdpServerTransport( IpAddress(mLoopback, 0) ));

        udpServerTransportPtr->open();
        int port = udpServerTransportPtr->getPort();

        ClientTransportAutoPtrPtr clientTransportAutoPtrPtr(
            new ClientTransportAutoPtr(
                new UdpClientTransport( IpAddress(mLoopback, port) )));

        return std::make_pair(
            ServerTransportPtr(udpServerTransportPtr),
            clientTransportAutoPtrPtr);
    }

    TransportPair UdpTransportFactory::createNonListeningTransports()
    {
        return std::make_pair(
            ServerTransportPtr( new UdpServerTransport( IpAddress(mLoopback, 0) ) ),
            ClientTransportAutoPtrPtr());
    }

    bool UdpTransportFactory::isConnectionOriented()
    {
        return false;
    }

    bool UdpTransportFactory::supportsTransportFilters()
    {
        return false;
    }

    std::string UdpTransportFactory::desc()
    {
        return "UdpTransportFactory (" + mLoopback + ")";
    }

#endif

    void initializeTransportFactories()
    {

#if RCF_FEATURE_IPV6==1
        const bool compileTimeIpv6 = true;
        ExceptionPtr ePtr;
        IpAddress("::1").resolve(ePtr);
        const bool runTimeIpv6 = (ePtr.get() == NULL);
#else
        const bool compileTimeIpv6 = false;
        const bool runTimeIpv6 = false;
#endif

#if RCF_FEATURE_NAMEDPIPE==1

        getTransportFactories().push_back(
            TransportFactoryPtr( new Win32NamedPipeTransportFactory()));

#endif

#if RCF_FEATURE_TCP==1

        getTransportFactories().push_back(
            TransportFactoryPtr( new TcpTransportFactory(IpAddress::V4)));

        getIpTransportFactories().push_back(
            TransportFactoryPtr( new TcpTransportFactory(IpAddress::V4)));

        if (compileTimeIpv6 && runTimeIpv6)
        {
            getTransportFactories().push_back(
                TransportFactoryPtr( new TcpTransportFactory(IpAddress::V6)));

            getIpTransportFactories().push_back(
                TransportFactoryPtr( new TcpTransportFactory(IpAddress::V6)));
        }

#endif

#if RCF_FEATURE_HTTP==1

        getTransportFactories().push_back(
            TransportFactoryPtr(new HttpTransportFactory()));

        getIpTransportFactories().push_back(
            TransportFactoryPtr(new HttpTransportFactory()));

        getTransportFactories().push_back(
            TransportFactoryPtr(new HttpsTransportFactory()));

        getIpTransportFactories().push_back(
            TransportFactoryPtr(new HttpsTransportFactory()));

#endif

#if RCF_FEATURE_LOCALSOCKET==1

        getTransportFactories().push_back(
            TransportFactoryPtr( new UnixLocalTransportFactory()));

#endif

#if RCF_FEATURE_UDP==1

        getTransportFactories().push_back(
            TransportFactoryPtr( new UdpTransportFactory(IpAddress::V4)));

        getIpTransportFactories().push_back(
            TransportFactoryPtr( new UdpTransportFactory(IpAddress::V4)));

        if (compileTimeIpv6 && runTimeIpv6)
        {
            getTransportFactories().push_back(
                TransportFactoryPtr( new UdpTransportFactory(IpAddress::V6)));

            getIpTransportFactories().push_back(
                TransportFactoryPtr( new UdpTransportFactory(IpAddress::V6)));
        }

#endif

    }

} // namespace RCF

max_stars_repo_name: ASMlover/study

max_issues_repo_name: ASMlover/study

max_forks_repo_name: ASMlover/study


text:
//=======================================================================
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
// If not, contact Office of Research, Indiana University,
// Bloomington, IN 47405.
//
// Permission to modify the code and to distribute the code is
// granted, provided the text of this NOTICE is retained, a notice if
// the code was modified is included with the above COPYRIGHT NOTICE
// and with the COPYRIGHT NOTICE in the LICENSE file, and that the
// LICENSE file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================

#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#error The vector_as_graph.hpp header requires partial specialization
#endif

#include <vector>
#include <list>
#include <boost/graph/vector_as_graph.hpp>
#include <boost/graph/graph_utility.hpp>

int
main()
{
  enum
  { r, s, t, u, v, w, x, y, N };
  char name[] = "rstuvwxy";
  typedef std::vector < std::list < int > > Graph;
  Graph g(N);
  g[r].push_back(v);
  g[s].push_back(r);
  g[s].push_back(r);
  g[s].push_back(w);
  g[t].push_back(x);
  g[u].push_back(t);
  g[w].push_back(t);
  g[w].push_back(x);
  g[x].push_back(y);
  g[y].push_back(u);
  boost::print_graph(g, name);
  return 0;
}

ext: cpp


text:
//  (C) Copyright John Maddock 2021.
//  Use, modification and distribution are subject to the
//  Boost Software License, Version 1.0. (See accompanying file
//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#define BOOST_MATH_NO_ATOMIC_INT

#include <boost/math/special_functions/bernoulli.hpp>
#include "compile_test/test_compile_result.hpp"

void compile_and_link_test()
{
   check_result<double>(boost::math::bernoulli_b2n<double>(4));
}

max_stars_repo_name: oleg-alexandrov/math

max_issues_repo_name: oleg-alexandrov/math

max_forks_repo_name: oleg-alexandrov/math


text:
//<developer>
//    <name>linapex 曹一峰</name>
//    <email>linapex@163.com</email>
//    <wx>superexc</wx>
//    <qqgroup>128148617</qqgroup>
//    <url>https://jsq.ink</url>
//    <role>pku engineer</role>
//    <date>2019-03-16 19:44:19</date>
//</624457060804726784>

/*
 *@文件
 *@eos/license中定义的版权
 **/

#include <boost/test/unit_test.hpp>
#include <boost/mpl/list.hpp>
#include <eosio/testing/tester.hpp>

#include <eosio/chain/snapshot.hpp>

#include <snapshot_test/snapshot_test.wast.hpp>
#include <snapshot_test/snapshot_test.abi.hpp>

#include <sstream>

using namespace eosio;
using namespace testing;
using namespace chain;

class snapshotted_tester : public base_tester {
public:
   snapshotted_tester(controller::config config, const snapshot_reader_ptr& snapshot, int ordinal) {
      FC_ASSERT(config.blocks_dir.filename().generic_string() != "."
         && config.state_dir.filename().generic_string() != ".", "invalid path names in controller::config");

      controller::config copied_config = config;
      copied_config.blocks_dir =
              config.blocks_dir.parent_path() / std::to_string(ordinal).append(config.blocks_dir.filename().generic_string());
      copied_config.state_dir =
              config.state_dir.parent_path() / std::to_string(ordinal).append(config.state_dir.filename().generic_string());

      init(copied_config, snapshot);
   }

   snapshotted_tester(controller::config config, const snapshot_reader_ptr& snapshot, int ordinal, int copy_block_log_from_ordinal) {
      FC_ASSERT(config.blocks_dir.filename().generic_string() != "."
         && config.state_dir.filename().generic_string() != ".", "invalid path names in controller::config");

      controller::config copied_config = config;
      copied_config.blocks_dir =
              config.blocks_dir.parent_path() / std::to_string(ordinal).append(config.blocks_dir.filename().generic_string());
      copied_config.state_dir =
              config.state_dir.parent_path() / std::to_string(ordinal).append(config.state_dir.filename().generic_string());

//创建所需块日志的副本，并可反转
      auto block_log_path = config.blocks_dir.parent_path() / std::to_string(copy_block_log_from_ordinal).append(config.blocks_dir.filename().generic_string());
      fc::create_directories(copied_config.blocks_dir);
      fc::copy(block_log_path / "blocks.log", copied_config.blocks_dir / "blocks.log");
      fc::copy(block_log_path / config::reversible_blocks_dir_name, copied_config.blocks_dir / config::reversible_blocks_dir_name );

      init(copied_config, snapshot);
   }
   /*Ned_block_ptr product_block（fc:：microseconds skip_time=fc:：millises（config:：block_interval_ms），uint32_t skip_flag=0/*skip_missed_block_penalty*/）override_
      返回_product_块（skip_time，false，skip_flag）；
   }

   有符号的\u块\u ptr产生\u空\u块（fc:：microseconds skip \u time=fc:：millises（config:：block \u interval \u ms），uint32 \u t skip \u flag=0/*skip \u missed \u块\u刑罚*/ )override {

      control->abort_block();
      return _produce_block(skip_time, true, skip_flag);
   }

   signed_block_ptr finish_block()override {
      return _finish_block();
   }

   bool validate() { return true; }
};

struct variant_snapshot_suite {
   using writer_t = variant_snapshot_writer;
   using reader_t = variant_snapshot_reader;
   using write_storage_t = fc::mutable_variant_object;
   using snapshot_t = fc::variant;

   struct writer : public writer_t {
      writer( const std::shared_ptr<write_storage_t>& storage )
      :writer_t(*storage)
      ,storage(storage)
      {

      }

      std::shared_ptr<write_storage_t> storage;
   };

   struct reader : public reader_t {
      explicit reader(const snapshot_t& storage)
      :reader_t(storage)
      {}
   };

   static auto get_writer() {
      return std::make_shared<writer>(std::make_shared<write_storage_t>());
   }

   static auto finalize(const std::shared_ptr<writer>& w) {
      w->finalize();
      return snapshot_t(*w->storage);
   }

   static auto get_reader( const snapshot_t& buffer) {
      return std::make_shared<reader>(buffer);
   }

};

struct buffered_snapshot_suite {
   using writer_t = ostream_snapshot_writer;
   using reader_t = istream_snapshot_reader;
   using write_storage_t = std::ostringstream;
   using snapshot_t = std::string;
   using read_storage_t = std::istringstream;

   struct writer : public writer_t {
      writer( const std::shared_ptr<write_storage_t>& storage )
      :writer_t(*storage)
      ,storage(storage)
      {

      }

      std::shared_ptr<write_storage_t> storage;
   };

   struct reader : public reader_t {
      explicit reader(const std::shared_ptr<read_storage_t>& storage)
      :reader_t(*storage)
      ,storage(storage)
      {}

      std::shared_ptr<read_storage_t> storage;
   };

   static auto get_writer() {
      return std::make_shared<writer>(std::make_shared<write_storage_t>());
   }

   static auto finalize(const std::shared_ptr<writer>& w) {
      w->finalize();
      return w->storage->str();
   }

   static auto get_reader( const snapshot_t& buffer) {
      return std::make_shared<reader>(std::make_shared<read_storage_t>(buffer));
   }

};

BOOST_AUTO_TEST_SUITE(snapshot_tests)

using snapshot_suites = boost::mpl::list<variant_snapshot_suite, buffered_snapshot_suite>;

BOOST_AUTO_TEST_CASE_TEMPLATE(test_exhaustive_snapshot, SNAPSHOT_SUITE, snapshot_suites)
{
   tester chain;

   chain.create_account(N(snapshot));
   chain.produce_blocks(1);
   chain.set_code(N(snapshot), snapshot_test_wast);
   chain.set_abi(N(snapshot), snapshot_test_abi);
   chain.produce_blocks(1);
   chain.control->abort_block();

   static const int generation_count = 8;
   std::list<snapshotted_tester> sub_testers;

   for (int generation = 0; generation < generation_count; generation++) {
//新建快照子级
      auto writer = SNAPSHOT_SUITE::get_writer();
      chain.control->write_snapshot(writer);
      auto snapshot = SNAPSHOT_SUITE::finalize(writer);

//在此快照中创建新子级
      sub_testers.emplace_back(chain.get_config(), SNAPSHOT_SUITE::get_reader(snapshot), generation);

//增加测试合同
      chain.push_action(N(snapshot), N(increment), N(snapshot), mutable_variant_object()
         ( "value", 1 )
      );

//生产块
      auto new_block = chain.produce_block();

//从检测仪中撤消自动挂起
      chain.control->abort_block();

      auto integrity_value = chain.control->calculate_integrity_hash();

//将该块推送到所有子测试人员，并在完成后验证数据库的完整性。
      for (auto& other: sub_testers) {
         other.push_block(new_block);
         BOOST_REQUIRE_EQUAL(integrity_value.str(), other.control->calculate_integrity_hash().str());
      }
   }
}

BOOST_AUTO_TEST_CASE_TEMPLATE(test_replay_over_snapshot, SNAPSHOT_SUITE, snapshot_suites)
{
   tester chain;

   chain.create_account(N(snapshot));
   chain.produce_blocks(1);
   chain.set_code(N(snapshot), snapshot_test_wast);
   chain.set_abi(N(snapshot), snapshot_test_abi);
   chain.produce_blocks(1);
   chain.control->abort_block();

   static const int pre_snapshot_block_count = 12;
   static const int post_snapshot_block_count = 12;

   for (int itr = 0; itr < pre_snapshot_block_count; itr++) {
//增加合同
      chain.push_action(N(snapshot), N(increment), N(snapshot), mutable_variant_object()
         ( "value", 1 )
      );

//生产块
      chain.produce_block();
   }

   chain.control->abort_block();
   auto expected_pre_integrity_hash = chain.control->calculate_integrity_hash();

//新建快照子级
   auto writer = SNAPSHOT_SUITE::get_writer();
   chain.control->write_snapshot(writer);
   auto snapshot = SNAPSHOT_SUITE::finalize(writer);

//在此快照中创建新子级
   snapshotted_tester snap_chain(chain.get_config(), SNAPSHOT_SUITE::get_reader(snapshot), 1);
   BOOST_REQUIRE_EQUAL(expected_pre_integrity_hash.str(), snap_chain.control->calculate_integrity_hash().str());

//推送更多块以建立块日志
   for (int itr = 0; itr < post_snapshot_block_count; itr++) {
//增加合同
      chain.push_action(N(snapshot), N(increment), N(snapshot), mutable_variant_object()
         ( "value", 1 )
      );

//生产和推块
      snap_chain.push_block(chain.produce_block());
   }

//验证末尾的哈希
   chain.control->abort_block();
   auto expected_post_integrity_hash = chain.control->calculate_integrity_hash();
   BOOST_REQUIRE_EQUAL(expected_post_integrity_hash.str(), snap_chain.control->calculate_integrity_hash().str());

//从快照子级、从快照重播块日志
   snapshotted_tester replay_chain(chain.get_config(), SNAPSHOT_SUITE::get_reader(snapshot), 2, 1);
   BOOST_REQUIRE_EQUAL(expected_post_integrity_hash.str(), snap_chain.control->calculate_integrity_hash().str());
}

BOOST_AUTO_TEST_SUITE_END()

max_stars_repo_name: linapex/eos-chinese

max_issues_repo_name: linapex/eos-chinese

max_forks_repo_name: linapex/eos-chinese


text:
/**
@file

\brief OpenNERO unit testing

This is an example unit test file for OpenNERO. We use Boost.Test as
the unit test framework. See other source files under test/, the
testOpenNERO target, and Boost.Test documentation
for additional information. These tests should be run with the ctest command.
*/
#define BOOST_TEST_MODULE TestOpenNERO
#define BOOST_TEST_DYN_LINK
#include <boost/test/unit_test.hpp>

BOOST_AUTO_TEST_SUITE( test_opennero )

BOOST_AUTO_TEST_CASE( test_example  )
{
    // this is just an example
    BOOST_TEST_MESSAGE("Testing OpenNERO...");

    // report and continue
    BOOST_CHECK(2*2 == 4);

    // report and stop
    BOOST_REQUIRE(2*2 == 4);

    // custom report and continue
    if (2*2 != 4)
        BOOST_ERROR("Unlikely error");

    // custom report and stop
    if (2*2 != 4)
        BOOST_FAIL("Unlikely error");

    // throw also works
    if (2*2 != 4) throw "Unlikely error";

    // custom report and continue
    BOOST_CHECK_MESSAGE(2*2 == 4, "2*2 was actually:" << 2*2);

    // report and continue, preferred method
    BOOST_CHECK_EQUAL(2*2,4);
}

BOOST_AUTO_TEST_SUITE_END()

max_stars_repo_name: thermalpilot/opennero

max_issues_repo_name: ikarpov/opennero

max_forks_repo_name: ikarpov/opennero


text:
///////////////////////////////////////////////////////////////////////////////
/// \file transform_intersection.hpp
/// transform() for InfiniteRangeRunStorage
//
//  Copyright 2006 Eric Niebler. Distributed under the Boost
//  Software License, Version 1.0. (See accompanying file
//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#ifndef BOOST_RANGE_RUN_STORAGE_ALGORITHM_DETAIL_TRANSFORM_INTERSECTION_EAN_07_27_2006_HPP
#define BOOST_RANGE_RUN_STORAGE_ALGORITHM_DETAIL_TRANSFORM_INTERSECTION_EAN_07_27_2006_HPP

#include <functional>
#include <boost/assert.hpp>
#include <boost/version.hpp>
#include <boost/detail/function2.hpp>
#if BOOST_VERSION <= 103400
# include <boost/spirit/fusion/sequence/tuple.hpp>
# include <boost/spirit/fusion/sequence/begin.hpp>
# include <boost/spirit/fusion/sequence/end.hpp>
# include <boost/spirit/fusion/iterator/next.hpp>
# include <boost/spirit/fusion/iterator/deref.hpp>
# include <boost/spirit/fusion/iterator/equal_to.hpp>
#else
# include <boost/fusion/tuple.hpp>
# include <boost/fusion/sequence/intrinsic/begin.hpp>
# include <boost/fusion/sequence/intrinsic/end.hpp>
# include <boost/fusion/iterator/next.hpp>
# include <boost/fusion/iterator/deref.hpp>
# include <boost/fusion/iterator/equal_to.hpp>
#endif
#include <boost/iterator/counting_iterator.hpp>
#include <boost/iterator/transform_iterator.hpp>
#include <boost/range_run_storage/utility/subrun.hpp>
#include <boost/range_run_storage/utility/subsequence.hpp>
#include <boost/range_run_storage/utility/run_cast.hpp>
#include <boost/range_run_storage/offset.hpp>
#include <boost/range_run_storage/set_at.hpp>
#include <boost/range_run_storage/end_offset.hpp>
#include <boost/range_run_storage/pre_run.hpp>
#include <boost/range_run_storage/post_run.hpp>
#include <boost/range_run_storage/traits/is_unit_run.hpp>
#include <boost/range_run_storage/traits/is_dense_runs.hpp>

namespace boost { namespace fusion
{
    namespace result_of {}
    namespace traits {}
    namespace meta
    {
        using namespace result_of;
        using namespace traits;
    }
}}

namespace boost { namespace range_run_storage
{
    namespace rrs = range_run_storage;

    namespace impl
    {
        // Increment one cursor or the other or both, depending on how their runs overlap
        template<typename L, typename R,
                 typename LU = typename has_unit_run<L>::type,
                 typename RU = typename has_unit_run<R>::type>
        struct increment
        {
            typedef void result_type;

            result_type operator ()(L &l, R &r) const
            {
                BOOST_ASSERT(!rrs::less(l.subrun(), r.subrun()) && !rrs::less(r.subrun(), l.subrun()));

                bool l_next = (rrs::end_offset(l.subrun()) <= rrs::end_offset(r.subrun()));
                bool r_next = (rrs::end_offset(r.subrun()) <= rrs::end_offset(l.subrun()));
                if(l_next)
                    l.next();
                if(r_next)
                    r.next();
            }
        };

        template<typename L, typename R>
        struct increment<L, R, mpl::true_, mpl::false_>
        {
            typedef void result_type;

            result_type operator ()(L &l, R &r) const
            {
                BOOST_ASSERT(!rrs::less(l.subrun(), r.subrun()) && !rrs::less(r.subrun(), l.subrun()));
                l.next();
            }
        };

        template<typename L, typename R>
        struct increment<L, R, mpl::false_, mpl::true_>
        {
            typedef void result_type;

            result_type operator ()(L &l, R &r) const
            {
                BOOST_ASSERT(!rrs::less(l.subrun(), r.subrun()) && !rrs::less(r.subrun(), l.subrun()));
                r.next();
            }
        };

        template<typename L, typename R>
        struct increment<L, R, mpl::true_, mpl::true_>
        {
            typedef void result_type;

            result_type operator ()(L &l, R &r) const
            {
                BOOST_ASSERT(!rrs::less(l.subrun(), r.subrun()) && !rrs::less(r.subrun(), l.subrun()));
                l.next();
                r.next();
            }
        };

        // work around annoying gcc mpl bug
        template<typename L, typename R>
        struct increment_gcc
          : increment<L, R>
        {};

    } // namespace impl

    namespace op
    {
        using mpl::_;

        struct increment
          : boost::detail::function2<impl::increment_gcc<_, _> >
        {};
    }

    namespace
    {
        op::increment const &increment = boost::detail::pod_singleton<op::increment>::instance;
    }

    namespace detail
    {
        template<
            typename LeftSubSequence
          , typename RightSubSequence
          , typename BinOp
          , typename Out
        >
        void transform_intersection_partial(
            LeftSubSequence &left
          , RightSubSequence &right
          , BinOp const &binop
          , Out &out
        )
        {
            while(!left.done() && !right.done())
            {
                if(rrs::less(left.subrun(), right.subrun()))
                {
                    left.skip_ahead_to(right.subrun());
                }
                else if(rrs::less(right.subrun(), left.subrun()))
                {
                    right.skip_ahead_to(left.subrun());
                }
                else
                {
                    // there is some range overlap
                    rrs::set_at(
                        out
                      , rrs::overlap(left.subrun(), right.subrun())
                      , binop(left.value(), right.value())
                    );

                    // increment either left or right or both
                    rrs::increment(left, right);
                }
            }
        }

        template<
            typename LeftBegin
          , typename LeftEnd
          , typename RightBegin
          , typename RightEnd
          , typename BinOp
          , typename Out
        >
        void transform_intersection_recurse(
            LeftBegin const &
          , LeftEnd const &
          , RightBegin const &
          , RightEnd const &
          , BinOp const &
          , Out &out
          , mpl::true_
          , mpl::true_
        )
        {}

        template<
            typename LeftBegin
          , typename LeftEnd
          , typename RightBegin
          , typename RightEnd
          , typename BinOp
          , typename Out
        >
        void transform_intersection_recurse(
            LeftBegin const &
          , LeftEnd const &
          , RightBegin const &
          , RightEnd const &
          , BinOp const &
          , Out &out
          , mpl::true_
          , mpl::false_
        )
        {}

        template<
            typename LeftBegin
          , typename LeftEnd
          , typename RightBegin
          , typename RightEnd
          , typename BinOp
          , typename Out
        >
        void transform_intersection_recurse(
            LeftBegin const &
          , LeftEnd const &
          , RightBegin const &
          , RightEnd const &
          , BinOp const &
          , Out &out
          , mpl::false_
          , mpl::true_
        )
        {}

        template<
            typename LeftBegin
          , typename LeftEnd
          , typename RightBegin
          , typename RightEnd
          , typename BinOp
          , typename Out
        >
        void transform_intersection_recurse(
            LeftBegin const &left_begin
          , LeftEnd const &left_end
          , RightBegin const &right_begin
          , RightEnd const &right_end
          , BinOp const &binop
          , Out &out
          , mpl::false_
          , mpl::false_
        )
        {
            typedef typename fusion::meta::next<LeftBegin>::type left_next_type;
            typedef typename fusion::meta::next<RightBegin>::type right_next_type;

            detail::transform_intersection_partial(
                *left_begin
              , *right_begin
              , binop
              , out
            );

            BOOST_ASSERT(rrs::is_done_and_empty(*left_begin) || rrs::is_done_and_empty(*right_begin));

            if(rrs::is_done_and_empty(*left_begin) && rrs::is_done_and_empty(*right_begin))
            {
                detail::transform_intersection_recurse(
                    fusion::next(left_begin)
                  , left_end
                  , fusion::next(right_begin)
                  , right_end
                  , binop
                  , out
                  , fusion::meta::equal_to<left_next_type, LeftEnd>()
                  , fusion::meta::equal_to<right_next_type, RightEnd>()
                );
            }
            else if(rrs::is_done_and_empty(*left_begin))
            {
                detail::transform_intersection_recurse(
                    fusion::next(left_begin)
                  , left_end
                  , right_begin
                  , right_end
                  , binop
                  , out
                  , fusion::meta::equal_to<left_next_type, LeftEnd>()
                  , mpl::false_()
                );
            }
            else
            {
                detail::transform_intersection_recurse(
                    left_begin
                  , left_end
                  , fusion::next(right_begin)
                  , right_end
                  , binop
                  , out
                  , mpl::false_()
                  , fusion::meta::equal_to<right_next_type, RightEnd>()
                );
            }
        }

        template<
            typename LeftSubSequences
          , typename RightSubSequences
          , typename BinOp
          , typename Out
        >
        void transform_intersection(
            LeftSubSequences const &left
          , RightSubSequences const &right
          , BinOp const &binop
          , Out &out
        )
        {
            typedef typename fusion::meta::begin<LeftSubSequences>::type left_begin_type;
            typedef typename fusion::meta::end<LeftSubSequences>::type left_end_type;
            typedef typename fusion::meta::begin<RightSubSequences>::type right_begin_type;
            typedef typename fusion::meta::end<RightSubSequences>::type right_end_type;

            detail::transform_intersection_recurse(
                fusion::begin(left)
              , fusion::end(left)
              , fusion::begin(right)
              , fusion::end(right)
              , binop
              , out
              , fusion::meta::equal_to<left_begin_type, left_end_type>()
              , fusion::meta::equal_to<right_begin_type, right_end_type>()
            );
        }
    } // namespace detail
}}

#endif // BOOST_RANGE_RUN_STORAGE_ALGORITHM_DETAIL_TRANSFORM_INTERSECTION_EAN_07_27_2006_HPP

ext: hpp


text:
//==============================================================================
//         Copyright 2003 - 2011   LASMEA UMR 6602 CNRS/Univ. Clermont II
//         Copyright 2009 - 2011   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 NT2_DSL_FUNCTIONS_TERMINAL_HPP_INCLUDED
#define NT2_DSL_FUNCTIONS_TERMINAL_HPP_INCLUDED

#include <boost/simd/dsl/functions/terminal.hpp>
#include <nt2/core/container/dsl/generator.hpp>
#include <nt2/core/container/dsl/size.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <nt2/include/functions/extent.hpp>
#include <boost/proto/traits.hpp>

namespace nt2
{
  namespace tag
  {
    /*! \brief Same as \classref{boost::simd::tag::terminal_} **/
    struct terminal_ : ext::elementwise_<terminal_>
    {
      typedef void is_nt2;

      typedef ext::elementwise_<terminal_> parent;
      template<class... Args>
      static BOOST_FORCEINLINE BOOST_AUTO_DECLTYPE dispatch(Args&&... args)
      BOOST_AUTO_DECLTYPE_BODY( dispatching_terminal_( ext::adl_helper(), static_cast<Args&&>(args)... ) )
    };
  }

  namespace ext
  {
    template<class Site, class... Ts>
    BOOST_FORCEINLINE generic_dispatcher<tag::terminal_, Site> dispatching_terminal_(adl_helper, boost::dispatch::meta::unknown_<Site>, boost::dispatch::meta::unknown_<Ts>...)
    {
      return generic_dispatcher<tag::terminal_, Site>();
    }
    template<class... Args>
    struct impl_terminal_;
  }

  /*! \brief Same as \funcref{boost::simd::terminal} **/
  template<class A0, class... Args>
  BOOST_FORCEINLINE BOOST_AUTO_DECLTYPE terminal(A0&& a0, Args&&... args)
  BOOST_AUTO_DECLTYPE_BODY( dispatching_terminal_( ext::adl_helper(), boost::dispatch::default_site_t<A0>(), boost::dispatch::meta::hierarchy_of_t<A0&&>(), boost::dispatch::meta::hierarchy_of_t<Args&&>()... )(static_cast<A0&&>(a0), static_cast<Args&&>(args)...) )
}

namespace nt2 { namespace ext
{
  //============================================================================
  // Terminal size is stored as a reference to the terminal value size
  //============================================================================
  template<class Domain, class Expr>
  struct size_of<nt2::tag::terminal_,Domain,0,Expr>
  {
    typedef typename boost::proto::result_of::value<Expr&>::type  term_t;
    typedef typename meta::call<tag::extent_(term_t)>::type       result_type;

    BOOST_FORCEINLINE result_type operator()(Expr& e) const
    {
      return nt2::extent(boost::proto::value(e));
    }
  };

  template<class Tag, class Domain, class Expr>
  struct size_of<Tag,Domain,0,Expr>
  {
    typedef typename boost::proto::result_of::value<Expr&>::type  term_t;
    typedef typename meta::call<Tag(term_t)>::type                value_t;
    typedef typename meta::call<tag::extent_(value_t)>::type      result_type;

    BOOST_FORCEINLINE result_type operator()(Expr& e) const
    {
      typename make_functor<Tag,Expr>::type callee;
      return nt2::extent(callee(boost::proto::value(e)));
    }
  };
} }

namespace nt2 { namespace details
{
  //============================================================================
  // Generator case for terminals
  //============================================================================
  template<class Domain, class Expr>
  struct generator<nt2::tag::terminal_, Domain, 0, Expr>
  {
    typedef typename boost::remove_const<Expr>::type expr;

    typedef container::expression< expr
                      , typename boost::proto::result_of::value<expr>::type
                      > result_type;

    BOOST_FORCEINLINE result_type operator()(Expr& e) const
    {
      return result_type(e);
    }
  };

  //============================================================================
  // Generator case for nullary expressions
  //============================================================================
  template<class Tag, class Domain, class Expr>
  struct generator<Tag, Domain, 0, Expr>
  {
    typedef container::expression
            < typename boost::remove_const<Expr>::type
            , typename meta::call < Tag ( typename boost::proto::result_of
                                                      ::value<Expr>::type
                                        )
                                  >::type
            > result_type;

    BOOST_FORCEINLINE result_type operator()(Expr& e) const
    {
      return result_type(e);
    }
  };
} }

#endif


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

  @copyright 2016 NumScale SAS
  @copyright 2016 J.T. Lapreste

  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_NEXT_HPP_INCLUDED
#define BOOST_SIMD_FUNCTION_NEXT_HPP_INCLUDED

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

 /*!

    @ingroup group-ieee
    Function object implementing next capabilities

    Returns the smallest representable value  strictly greater than the parameter

    @par Semantic:

    @code
    T r = next(x);
    @endcode

    computes the smallest value strictly greater than x in type T

    @see nextafter, prev, successor, predecessor

  **/
  const boost::dispatch::functor<tag::next_> next = {};
} }
#endif

#include <boost/simd/function/scalar/next.hpp>
#include <boost/simd/function/simd/next.hpp>

#endif


text:
#include <typeinfo>
#include <algorithm>

#include <boost/foreach.hpp>

#include <autonomy/entity/asteroid.hpp>
#include <autonomy/action/mine.hpp>
#include <autonomy/action/destroy_entity.hpp>

BOOST_CLASS_EXPORT(autonomy::entity_base<autonomy::entity::asteroid>);

BOOST_CLASS_EXPORT(autonomy::entity::asteroid);

namespace autonomy
{
    namespace entity
    {
        void asteroid::controller(size_t which_queue)
        {
            if ( get_fuel() == 0 )
            {
                universe()->send_action(which_queue, new action::hide_entity(*this));
                drain_fuel(1);
            }
            else if ( get_fuel() < 0 )
            {
                drain_fuel(1);
            }
            else if ( get_fuel() < -2 )
            {
                universe()->send_action(which_queue, new action::destroy_entity(*this));
            }
        }
    }
}

max_stars_repo_name: medlefsen/autonomy

max_issues_repo_name: medlefsen/autonomy

max_forks_repo_name: medlefsen/autonomy


text:
//  (C) Copyright Nick Thompson 2020.
//  Use, modification and distribution are subject to the
//  Boost Software License, Version 1.0. (See accompanying file
//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#include <iostream>
#include <boost/math/tools/luroth_expansion.hpp>
#include <boost/math/constants/constants.hpp>

#ifndef BOOST_MATH_STANDALONE
#include <boost/multiprecision/mpfr.hpp>
using boost::multiprecision::mpfr_float;
#endif // BOOST_MATH_STANDALONE

using boost::math::constants::pi;
using boost::math::tools::luroth_expansion;

int main() {
    #ifndef BOOST_MATH_STANDALONE
    using Real = mpfr_float;
    mpfr_float::default_precision(1024);
    #else
    using Real = long double;
    #endif

    auto luroth = luroth_expansion(pi<Real>());
    std::cout << luroth << "\n";
}


text:
#include <ros/ros.h>
#include <kst_servoing.hpp>
#include <boost/asio.hpp>

int main(int argc, char** argv){
	ros::init(argc, argv, "KSTRosNode");

	KSTServoing s;
	boost::asio::io_context io_context;
	std::string robot_ip = "172.31.1.147";
	s(robot_ip, io_context);

}

max_stars_repo_name: bingogome/kuka-sunrise-toolbox-cpp-ros

max_issues_repo_name: bingogome/kuka-sunrise-toolbox-cpp-ros

max_forks_repo_name: bingogome/kuka-sunrise-toolbox-cpp-ros


text:
/*
 * This file is part of the CitizenFX project - http://citizen.re/
 *
 * See LICENSE and MENTIONS in the root of the source tree for information
 * regarding licensing.
 */

#include "StdInc.h"
#include "fiDevice.h"
#include "Hooking.h"
#include "boost/assign.hpp"

#include <boost/algorithm/string.hpp>

#include <LaunchMode.h>

#include <VFSManager.h>
#include <VFSRagePackfile7.h>
#include <RelativeDevice.h>

#include <CL2LaunchMode.h>

#include <Error.h>

using namespace std::string_literals;

static int(__cdecl* origSetFunc)(void* extraContentMgr, void* a2, const char* deviceName);
int someFunc(void* a1, void* a2, const char* a3)
{
	int someResult = origSetFunc(a1, a2, a3);

	std::string dlcName = std::string(a3);
	dlcName = dlcName.substr(0, dlcName.find(":"));

	auto exists = [] (const std::string& path)
	{
		auto device = rage::fiDevice::GetDevice(path.c_str(), true);

		if (device)
		{
			return (device->GetFileAttributes(path.c_str()) != INVALID_FILE_ATTRIBUTES);
		}

		return false;
	};

	{
		std::string name = "citizen:/dlc/" + dlcName + "/";

		if (exists(name))
		{
			{
				rage::fiDeviceRelative* dlc = new rage::fiDeviceRelative();
				dlc->SetPath(name.c_str(), true);
				dlc->Mount((dlcName + ":/").c_str());
			}

			{
				rage::fiDeviceRelative* dlc = new rage::fiDeviceRelative();
				dlc->SetPath(name.c_str(), true);
				dlc->Mount((dlcName + "CRC:/").c_str());
			}
		}
	}

	{
		std::string name = "citizen:/dlc/" + dlcName + "CRC/";

		if (exists(name))
		{
			rage::fiDeviceRelative* dlc = new rage::fiDeviceRelative();
			dlc->SetPath(name.c_str(), true);
			dlc->Mount((dlcName + "CRC:/").c_str());
		}
	}

	return someResult;
}

static HookFunction hookFunction([]()
{
	hook::set_call(&origSetFunc, hook::pattern("66 39 79 38 74 06 4C 8B  41 30 EB 07 4C 8D").count(1).get(0).get<void>(19));
	hook::call(hook::pattern("66 39 79 38 74 06 4C 8B  41 30 EB 07 4C 8D").count(1).get(0).get<void>(19), someFunc);
});

#include <ShlObj.h>
#include <boost/algorithm/string.hpp>

class PathFilteringDevice : public vfs::RelativeDevice
{
public:
	PathFilteringDevice(const std::string& path)
		: vfs::RelativeDevice(path)
	{

	}

	virtual THandle Open(const std::string& fileName, bool readOnly) override
	{
		std::string relPath = fileName.substr(strlen("commonFilter:/"));

		boost::algorithm::replace_all(relPath, "\\", "/");
		boost::algorithm::to_lower(relPath);

		if (relPath == "data/levels/gta5/trains.xml" ||
			relPath == "data/materials/materials.dat" ||
			relPath == "data/relationships.dat" ||
			relPath == "data/dlclist.xml")
		{
			return InvalidHandle;
		}

		return RelativeDevice::Open(fileName, readOnly);
	}
};

static InitFunction initFunction([] ()
{
	rage::fiDevice::OnInitialMount.Connect([] ()
	{
		std::wstring citPath = MakeRelativeCitPath(L"citizen");

		std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> converter;
		std::string citRoot = converter.to_bytes(citPath) + "\\";

		rage::fiDeviceRelative* device = new rage::fiDeviceRelative();
		device->SetPath(citRoot.c_str(), true);
		device->Mount("citizen:/");

		// mount cfx:/ -> citizen folder
		std::string fxRoot = converter.to_bytes(MakeRelativeCitPath(L""));

		rage::fiDeviceRelative* cfxDevice = new rage::fiDeviceRelative();
		cfxDevice->SetPath(fxRoot.c_str(), true);
		cfxDevice->Mount("cfx:/");

		std::wstring cachePath = MakeRelativeCitPath(fmt::sprintf(L"cache%s", ToWide(launch::GetPrefixedLaunchModeKey("\\"))));

		if (GetFileAttributes(cachePath.c_str()) == INVALID_FILE_ATTRIBUTES)
		{
			CreateDirectory(cachePath.c_str(), nullptr);
		}

		std::string cacheRoot = converter.to_bytes(cachePath) + "\\";

		rage::fiDeviceRelative* cacheDevice = new rage::fiDeviceRelative();
		cacheDevice->SetPath(cacheRoot.c_str(), true);
		cacheDevice->Mount("rescache:/");

		{
			std::string narrowPath;

			if (!CfxIsSinglePlayer())
			{
				std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> converter;
				narrowPath = converter.to_bytes(MakeRelativeCitPath(L"citizen\\common\\"s));

				fwRefContainer<PathFilteringDevice> filterDevice = new PathFilteringDevice(narrowPath);
				vfs::Mount(filterDevice, "commonFilter:/");

				narrowPath = "commonFilter:/";
			}
			else if (CfxIsSinglePlayer())
			{
				std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> converter;
				narrowPath = converter.to_bytes(MakeRelativeCitPath(L"citizen\\common"s + (CfxIsSinglePlayer() ? L"-sp" : L"")));
			}
#if 0
			else
			{
				static fwRefContainer<vfs::RagePackfile7> citizenCommon = new vfs::RagePackfile7();
				if (!citizenCommon->OpenArchive("citizen:/citizen_common.rpf", true))
				{
					FatalError("Opening citizen_common.rpf failed!");
				}

				vfs::Mount(citizenCommon, "citizen_common:/");
				narrowPath = "citizen_common:/";
			}
#endif

			rage::fiDeviceRelative* relativeDevice = new rage::fiDeviceRelative();
			relativeDevice->SetPath(narrowPath.c_str(), nullptr, true);
			relativeDevice->Mount("common:/");

			rage::fiDeviceRelative* relativeDeviceCrc = new rage::fiDeviceRelative();
			relativeDeviceCrc->SetPath(narrowPath.c_str(), nullptr, true);
			relativeDeviceCrc->Mount("commoncrc:/");

			rage::fiDeviceRelative* relativeDeviceGc = new rage::fiDeviceRelative();
			relativeDeviceGc->SetPath(narrowPath.c_str(), nullptr, true);
			relativeDeviceGc->Mount("gamecache:/");

		}

		{
			std::string narrowPath;

			if (CfxIsSinglePlayer() || true)
			{
				std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> converter;
				narrowPath = converter.to_bytes(MakeRelativeCitPath(L"citizen\\platform"s + (CfxIsSinglePlayer() ? L"-sp" : L"")));
			}
			else
			{
				static fwRefContainer<vfs::RagePackfile7> citizenPlatform = new vfs::RagePackfile7();
				if (!citizenPlatform->OpenArchive("citizen:/citizen_platform.rpf", true))
				{
					FatalError("Opening citizen_platform.rpf failed!");
				}

				vfs::Mount(citizenPlatform, "citizen_platform:/");
				narrowPath = "citizen_platform:/";
			}

			rage::fiDeviceRelative* relativeDevice = new rage::fiDeviceRelative();
			relativeDevice->SetPath(narrowPath.c_str(), nullptr, true);
			relativeDevice->Mount("platform:/");

			rage::fiDeviceRelative* relativeDeviceCrc = new rage::fiDeviceRelative();
			relativeDeviceCrc->SetPath(narrowPath.c_str(), nullptr, true);
			relativeDeviceCrc->Mount("platformcrc:/");
		}

		if (CfxIsSinglePlayer() || true)
		{
			rage::fiFindData findData;
			auto handle = cfxDevice->FindFirst("cfx:/addons/", &findData);

			if (handle != -1)
			{
				do
				{
					if ((findData.fileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
					{
						std::string fn = findData.fileName;

						if (boost::algorithm::ends_with(fn, ".rpf"))
						{
							std::string fullFn = "cfx:/addons/" + fn;
							std::string addonRoot = "addons:/" + fn.substr(0, fn.find_last_of('.')) + "/";

							rage::fiPackfile* addonPack = new rage::fiPackfile();
							addonPack->OpenPackfile(fullFn.c_str(), true, false, 0);
							addonPack->Mount(addonRoot.c_str());

							{
								rage::fiDeviceRelative* relativeDevice = new rage::fiDeviceRelative();
								relativeDevice->SetPath((addonRoot + "platform/").c_str(), nullptr, true);
								relativeDevice->Mount("platform:/");

								rage::fiDeviceRelative* relativeDeviceCrc = new rage::fiDeviceRelative();
								relativeDeviceCrc->SetPath((addonRoot + "platform/").c_str(), nullptr, true);
								relativeDeviceCrc->Mount("platformcrc:/");
							}

							{
								rage::fiDeviceRelative* relativeDevice = new rage::fiDeviceRelative();
								relativeDevice->SetPath((addonRoot + "common/").c_str(), nullptr, true);
								relativeDevice->Mount("common:/");

								rage::fiDeviceRelative* relativeDeviceCrc = new rage::fiDeviceRelative();
								relativeDeviceCrc->SetPath((addonRoot + "common/").c_str(), nullptr, true);
								relativeDeviceCrc->Mount("commoncrc:/");
							}
						}
					}
				} while (cfxDevice->FindNext(handle, &findData));

				cfxDevice->FindClose(handle);
			}
		}

		{
			PWSTR appDataPath;
			if (SUCCEEDED(SHGetKnownFolderPath(FOLDERID_RoamingAppData, 0, nullptr, &appDataPath)))
			{
				// create the directory if not existent
				std::wstring cfxPath = std::wstring(appDataPath) + L"\\CitizenFX";
				CreateDirectory(cfxPath.c_str(), nullptr);

				std::wstring profilePath = cfxPath + L"\\";

				rage::fiDeviceRelative* fxUserDevice = new rage::fiDeviceRelative();
				fxUserDevice->SetPath(converter.to_bytes(profilePath).c_str(), false);
				fxUserDevice->Mount("fxd:/");

				CoTaskMemFree(appDataPath);
			}
		}

		// look for files in citizen\common\data
		rage::fiFindData findData;
		auto handle = device->FindFirst("citizen:/common/data/", &findData);

		if (handle != -1)
		{
			do
			{
				if ((findData.fileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
				{
					AddCrashometry(fmt::sprintf("common_data_%s", findData.fileName), "%d", findData.fileSize);
				}
			} while (device->FindNext(handle, &findData));

			device->FindClose(handle);
		}

		// look for files in citizen\platform\data too
		handle = device->FindFirst("citizen:/platform/data/", &findData);

		if (handle != -1)
		{
			do
			{
				if ((findData.fileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
				{
					AddCrashometry(fmt::sprintf("platform_data_%s", findData.fileName), "%d", findData.fileSize);
				}
			} while (device->FindNext(handle, &findData));

			device->FindClose(handle);
		}
	});
});

max_stars_repo_name: citizenfx-ci/fivem

max_issues_repo_name: utkuali/fivem

max_forks_repo_name: utkuali/fivem


text:
#include "bindings-resources.h"
#include "bindings-gfx.h"
#include "bindings.h"

#include "../luaapi/types.h"
#include "../luaapi/macros.h"
#include "../luaapi/classes.h"

#include "../gusgame.h"
#include "../gfx.h"
#include "../script.h"
#ifndef DEDICATED_ONLY
#include "../sound.h"
#include "sound/sfx.h"
#endif
#include "../part_type.h"
#include "../weapon_type.h"
#include "game/CMap.h"

//TEMP:
#include "../sprite_set.h"
#include "../sprite.h"

#ifndef DEDICATED_ONLY
#include "../font.h"
#endif
#include <cmath>
#include <string>
#include <list>
#include <iostream>
#include <vector>
using std::cerr;
using std::endl;
#include <boost/lexical_cast.hpp>
#include <boost/bind.hpp>
using boost::lexical_cast;

namespace LuaBindings
{

#ifndef DEDICATED_ONLY
LuaReference FontMetaTable;
LuaReference SpriteSetMetaTable;
LuaReference SoundMetaTable;
#endif
//LuaReference PartTypeMetaTable;
//LuaReference WeaponTypeMetaTable;

enum FontFlags
{
	None        = 0,
	CenterV     = (1<<0),
	CenterH     = (1<<1),
	Shadow      = (1<<2),
	Formatting  = (1<<3),
	Right       = (1<<4),
	Bottom      = (1<<5),
};

#ifndef DEDICATED_ONLY

/*! sprites_load(name)

	Loads and returns a SpriteSet object of the sprite set with the passed name.

	If the sprite set couldn't be loaded, nil is returned.
*/
int l_sprites_load(lua_State* L)
{
	LuaContext context(L);

	const char* n = lua_tostring(context, 1);
	if(!n) return 0;

	SpriteSet *s = spriteList.load(n);
	if(!s) return 0;

	context.pushFullReference(*s, LuaBindings::SpriteSetMetaTable);

	return 1;
}

/*! SpriteSet:render(bitmap, frame, x, y)

	Draws the frame //frame// of the sprite set on //bitmap// with the pivot at position (x, y).
*/
METHODC(SpriteSet, sprites_render,
	//ALLEGRO_BITMAP* b = *static_cast<ALLEGRO_BITMAP **>(lua_touserdata(context, 2));
	ALLEGRO_BITMAP* b = ASSERT_OBJECT(ALLEGRO_BITMAP, 2);

	// All images in doubleRes.
	int frame = lua_tointeger(context, 3);
	int x = int(lua_tonumber(context, 4) * 2);
	int y = int(lua_tonumber(context, 5) * 2);
	p->getSprite(frame)->draw(b, x, y, blitter);

	return 0;
)

/*! SpriteSet:render_skinned_box(bitmap, x1, y1, x2, y2, color)

	Draws the sprite set as a skinned box with the rectangle (x1, y1) - (x2, y2)
	and background color //color//.

	**Note that in versions before 0.9c, color was specified as
	three parameters. This has been deprecated.**
*/
#ifndef NO_DEPRECATED
METHODC(SpriteSet, sprites_render_skinned_box,  {
	ALLEGRO_BITMAP* b = ASSERT_OBJECT(ALLEGRO_BITMAP, 2);

	// All images in doubleRes.
	int x1 = int(lua_tonumber(context, 3) * 2);
	int y1 = int(lua_tonumber(context, 4) * 2);
	int x2 = int(lua_tonumber(context, 5) * 2);
	int y2 = int(lua_tonumber(context, 6) * 2);
	int c = lua_tointeger(context, 7);

	if(lua_gettop(context) >= 9) // Deprecated
	{
		LUA_WLOG_ONCE("The r, g, b version of render_skinned_box is deprecated, replace the r, g, b parameters by color(r, g, b)");
		int g = lua_tointeger(context, 8);
		int b = lua_tointeger(context, 9);
		c = makecol(c, g, b);
	}

	p->drawSkinnedBox(b, blitter, Rect(x1, y1, x2+1, y2+1), c);

	return 0;
})
#else
METHODC(SpriteSet, sprites_render_skinned_box,  (
	ALLEGRO_BITMAP* b = ASSERT_OBJECT(ALLEGRO_BITMAP, 2);

	// All images in doubleRes.
	int x1 = int(lua_tonumber(context, 3) * 2);
	int y1 = int(lua_tonumber(context, 4) * 2);
	int x2 = int(lua_tonumber(context, 5) * 2);
	int y2 = int(lua_tonumber(context, 6) * 2);
	int c = lua_tointeger(context, 7);
	p->drawSkinnedBox(b, blitter, Rect(x1, y1, x2+1, y2+1), c);

	return 0;
))
#endif

/*! SpriteSet:frames()

	Returns the number of frames in this sprite set.
*/
METHODC(SpriteSet, sprites_frames,  {
	context.push(static_cast<int>(p->getFramesWidth()));
	return 1;
})

/*! font_load(name)

	Loads and returns a Font object of the font with the passed name.

	If the font couldn't be loaded, nil is returned.
*/
int l_font_load(lua_State* L)
{
	LuaContext context(L);

	char const* n = lua_tostring(L, 1);
	if(!n) return 0;

	Font *f = fontLocator.load(n);
	if(!f) return 0;

	context.pushFullReference(*f, LuaBindings::FontMetaTable);

	return 1;
}

int l_font_load2(lua_State* L)
{
	LuaContext context(L);

	char const* n = lua_tostring(L, 2);

	if(!n) return 0;

	Font *f = fontLocator.load(n);
	if(!f) return 0;

	context.pushFullReference(*f, LuaBindings::FontMetaTable);
	lua_pushvalue(L, -1);
	lua_setfield(L, 1, n);
	return 1;
}

/*! Font:render(bitmap, string, x, y[, color[, flags]])

	Draws the text 'string' on 'bitmap' at the position (x, y).

	If //color// is supplied, it draws the text with that color,
	otherwise it draws the text white.

	**Note that in versions before 0.9c, color was specified as
	three parameters. This has been deprecated.**

	//flags// can be a sum of these values:
	* Font.None : No flags (default).
	* Font.CenterV : Center the text vertically with y at the middle.
	* Font.CenterH : Center the text horizontally with x at the middle.
	* Font.Shadow : Draw a shadow under the text.

	Font.Formatting : Draw the text with formatting.

*/

typedef std::pair<int, int> pair_int;

METHODC(Font, font_render,  {
	int params = lua_gettop(context);
	if(params < 5)
		return 0;

	//ALLEGRO_BITMAP* b = *static_cast<ALLEGRO_BITMAP **>(lua_touserdata(L, 2));
	ALLEGRO_BITMAP* b = ASSERT_OBJECT(ALLEGRO_BITMAP, 2);

	char const* sc = lua_tostring(context, 3);
	if(!sc)
		return 0;

	std::string s(sc);

	// All images in doubleRes.
	int x = int(lua_tonumber(context, 4) * 2);
	int y = int(lua_tonumber(context, 5) * 2);

	int cr = 255;
	int cg = 255;
	int cb = 255;
	int flags = 0;

	if(params >= 6)
	{
		int c = lua_tointeger(context, 6);
		if(params >= 8)
		{
			LUA_WLOG_ONCE("The r, g, b version of Font:render is deprecated, replace the r, g, b parameters by color(r, g, b)");
			cr = c;
			cg = lua_tointeger(context, 7);
			cb = lua_tointeger(context, 8);
			if(params >= 9)
				flags = lua_tointeger(context, 9);
		}
		else
		{
			cr = getr(c);
			cg = getg(c);
			cb = getb(c);
			if(params >= 7)
				flags = lua_tointeger(context, 7);
		}
	}

	int realFlags = 0;

	if(flags & Shadow)
		realFlags |= Font::Shadow;
	if(flags & Formatting)
		realFlags |= Font::Formatting;

	if(flags & (CenterV | CenterH | Right | Bottom))
	{
		pair_int dim = p->getDimensions(s, 0, realFlags);

		if(flags & Right)
			x -= dim.first;
		else if(flags & CenterH)
			x -= (dim.first - 1) / 2;
		if(flags & Bottom)
			y -= dim.second;
		else if(flags & CenterV)
			y -= (dim.second - 1) / 2;
	}

	int fact = (blitter.type() != BlitterContext::Alpha ? 256 : blitter.fact());
	p->draw(b, s, x, y, 0, fact, cr, cg, cb, realFlags);

	return 0;
})

//! version 0.9c

/*! sounds

	This table returns Sound objects when indexed with a valid sound name, and
	nil otherwise.

	Example:
	<code>
	local mySound = sounds["bazooka.wav"]
	mySound:play(10, 10)
	</code>
*/

int l_sound_load2(lua_State* L)
{
	if(bDedicated) return 0;
	if(!sfx) return 0;

	LuaContext context(L);

	char const* n = lua_tostring(L, 2);

	if(!n) return 0;

	Sound* s = soundList.load(n);
	if(!s) return 0;

	context.pushFullReference(*s, LuaBindings::SoundMetaTable);
	lua_pushvalue(L, -1);
	lua_setfield(L, 1, n);
	return 1;
}

/*! Sound:play([x, y | object] [, loudness, pitch, pitchVariation])

	Plays a sound either at position (x, y) on the map, or attached to
	object //object// (depending on which is passed to the function).
*/
METHODC(Sound, sound_play,  {
	lua_Number loudness = 100.0;
	lua_Number pitch = 1.0;
	lua_Number pitchVariation = 1.0;

	if(CGameObject* obj = getObject<CGameObject>(context, 2))
	{
		int params = lua_gettop(context);
		switch(params)
		{
			default: if(params < 2) return 0;
			case 5:  pitchVariation = lua_tonumber(context, 6);
			case 4:  pitch = lua_tonumber(context, 5);
			case 3:  loudness = lua_tonumber(context, 4);
			case 2:  break;
		}

		//CGameObject* obj = *static_cast<CGameObject**>(lua_touserdata(context, 2));

		p->play2D(obj, (float)loudness, (float)pitch, (float)pitchVariation);
	}
	else
	{
		int params = lua_gettop(context);

		switch(params)
		{
			default: if(params < 3) return 0;
			case 6:  pitchVariation = lua_tonumber(context, 6);
			case 5:  pitch = lua_tonumber(context, 5);
			case 4:  loudness = lua_tonumber(context, 4);
			case 3:  break;
		}

		lua_Number x = lua_tonumber(context, 2);
		lua_Number y = lua_tonumber(context, 3);

		p->play2D(Vec((float)x, (float)y), (float)loudness, (float)pitch, (float)pitchVariation);
	}

	return 0;
})
#endif

//! version any

/*! map_is_loaded()

	Returns true if a map is loaded, otherwise false.
*/
int l_map_is_loaded(lua_State* L)
{
	lua_pushboolean(L, game.isMapReady());

	return 1;
}

int l_load_script(lua_State* L)
{
	char const* s = lua_tostring(L, 2);
	if(!s)
		return 0;
	Script* script = scriptLocator.load(s);

	if(!script) {
		//notes << "Lua load script: cannot load " << s << endl;
		return 0;
	}

	// Return the allocated table
	lua_pushvalue(L, 2);
	lua_rawget(L, LUA_GLOBALSINDEX);
	return 1;
}

/*! load_particle(name)

	Loads a particle type with the name //name// and returns it as a
	ParticleType object.
*/
int l_load_particle(lua_State* L)
{
	LuaContext context(L);

	char const* s = lua_tostring(L, 1);
	if(!s)
		return 0;

	PartType* type = partTypeList.load(s);
	if(!type)
		return 0;

	type->pushLuaReference(context);
	return 1;
}

/*! weapon_random()

	Returns a random WeaponType object.
*/
int l_weapon_random(lua_State* L)
{
	LuaContext context(L);

	if(gusGame.weaponList.size() == 0) {
		errors << "Lua: l_weapon_random: no weapons available" << endl;
		return 0;
	}

	WeaponType* p = gusGame.weaponList[rndInt(gusGame.weaponList.size())];
	p->pushLuaReference(context);
	return 1;
}

/*! weapon_count()

	Returns the total number of weapons.
*/
int l_weapon_count(lua_State* L)
{
	lua_pushinteger(L, gusGame.weaponList.size());
	return 1;
}

/*! WeaponType:next()

	Returns the next weapon type after this one.
*/
METHODC(WeaponType, weapon_next,  {
	if(gusGame.weaponList.size() == 0) return 0;
	size_t n = p->getIndex() + 1;
	if(n >= gusGame.weaponList.size())
		n = 0;
	gusGame.weaponList[n]->pushLuaReference(context);
	return 1;
})

/*! WeaponType:prev()

	Returns the previous weapon type after this one.
*/
METHODC(WeaponType, weapon_prev,  {
	if(gusGame.weaponList.size() == 0) return 0;
	size_t n = p->getIndex();
	if(n == 0)
		n = gusGame.weaponList.size() - 1;
	else
		--n;
	gusGame.weaponList[n]->pushLuaReference(context);
	return 1;
})

/*! WeaponType:name()

	Returns the name of this weapon type.
*/
METHODC(WeaponType, weapon_name,  {
	lua_pushstring(context, p->name.c_str());
	return 1;
})

/*! WeaponType:reload_time()

	Returns the time it takes for this weapon type to reload.
*/
METHODC(WeaponType, weapon_reload_time,  {
	context.push(p->reloadTime);
	return 1;
})

/*! WeaponType:ammo()

	Returns the amount of ammo for this weapon type when reloaded.
*/
METHODC(WeaponType, weapon_ammo,  {
	context.push(p->ammo);
	return 1;
})

/*
BINOP(WeaponType, weapon_eq,  {
	context.push(a == b);
	return 1;
})*/

METHODC(PartType, parttype_put,  {
	float x = 0.f;
	float y = 0.f;
	float xspd = 0.f;
	float yspd = 0.f;
	Angle angle(0.0);

	int params = lua_gettop(context);
	switch(params)
	{
		default: if(params < 3) return 0;
		case 6:  angle = Angle(lua_tonumber(context, 6));
		case 5:  yspd = (float)lua_tonumber(context, 5);
		case 4:  xspd = (float)lua_tonumber(context, 4);
		case 3:  y = (float)lua_tonumber(context, 3);
		case 2:  x = (float)lua_tonumber(context, 2);
	}

	CGameObject* last = p->newParticle(p, Vec(x, y), Vec(xspd, yspd), 1, 0, angle);

	if(last)
	{
		last->pushLuaReference(context);
		return 1;
	}

	return 0;
})

void initResources(LuaContext& context)
{
	AssertStack as(context);

	context.functions()
		("load_particle", l_load_particle)
		("weapon_random", l_weapon_random)
		("weapon_count", l_weapon_count)
#ifndef DEDICATED_ONLY
		("sprites_load", l_sprites_load)
		("font_load", l_font_load)
#endif
		("map_is_loaded", l_map_is_loaded)
	;

	CLASS_(PartType,
		("put", l_parttype_put)
	)

	CLASS_(WeaponType,
		("next", l_weapon_next)
		("prev", l_weapon_prev)
		("name", l_weapon_name)
		("reload_time", l_weapon_reload_time)
		("ammo", l_weapon_ammo)
	)

#ifndef DEDICATED_ONLY
	// Font method and metatable

	CLASS(Font,
		("render", l_font_render)
	)

	ENUM(Font,
		("None", None)
		("CenterV", CenterV)
		("CenterH", CenterH)
		("Right", Right)
		("Bottom", Bottom)
		("Shadow", Shadow)
		("Formatting", Formatting)
	)

	CLASS(Sound,
		("play", l_sound_play)
	)

	CLASS(SpriteSet,
		("render", l_sprites_render)
		("render_skinned_box", l_sprites_render_skinned_box)
		("frames", l_sprites_frames)
	)

	REQUEST_TABLE("fonts", l_font_load2);
	REQUEST_TABLE("sounds", l_sound_load2);

#endif
	// Global metatable

	lua_pushvalue(context, LUA_GLOBALSINDEX);

	lua_newtable(context);
	context.tableFunction("__index", l_load_script);

	lua_setmetatable(context, -2);
	context.pop(1); // Pop global table

	//std::cerr << "Old: " << as.stack << std::endl;
	//std::cerr << "New: " << lua_gettop(context) << std::endl;
}

}

max_stars_repo_name: JiPRA/openlierox

max_issues_repo_name: JiPRA/openlierox

max_forks_repo_name: JiPRA/openlierox


text:
// Copyright 2014 Tony Wasserka
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//     * Neither the name of the owner nor the names of its contributors may
//       be used to endorse or promote products derived from this software
//       without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// Enable this for detailed XML overview of parser results
// #define BOOST_SPIRIT_DEBUG

#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/phoenix/phoenix.hpp>
#include <boost/spirit/include/qi.hpp>

#include "nihstro/parser_assembly.h"
#include "nihstro/parser_assembly_private.h"

#include "nihstro/shader_binary.h"
#include "nihstro/shader_bytecode.h"

namespace spirit = boost::spirit;
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::qi::ascii;
namespace phoenix = boost::phoenix;

using spirit::_1;
using spirit::_2;
using spirit::_3;
using spirit::_4;

using namespace nihstro;

// Adapt parser data structures for use with boost::spirit

BOOST_FUSION_ADAPT_STRUCT(
    StatementInstruction,
    (OpCode, opcode)
    (std::vector<Expression>, expressions)
)

template<>
FloatOpParser<ParserIterator>::FloatOpParser(const ParserContext& context)
                : FloatOpParser::base_type(float_instruction),
                  common(context),
                  opcodes_float(common.opcodes_float),
                  expression(common.expression),
                  end_of_statement(common.end_of_statement),
                  diagnostics(common.diagnostics) {

        // Setup rules

        auto comma_rule = qi::lit(',');

        for (int i = 0; i < 4; ++i) {
            // Make sure that a mnemonic is always followed by a space (such that e.g. "addbla" fails to match)
            opcode[i] = qi::no_case[qi::lexeme[opcodes_float[i] >> &ascii::space]];
        }

        // chain of arguments for each group of opcodes
        expression_chain[0] = expression;
        for (int i = 1; i < 4; ++i) {
            expression_chain[i] = expression_chain[i - 1] >> comma_rule > expression;
        }

        // e.g. "add o1, t2, t5"
        float_instr[0] = opcode[0] > expression_chain[0];
        float_instr[1] = opcode[1] > expression_chain[1];
        float_instr[2] = opcode[2] > expression_chain[2];
        float_instr[3] = opcode[3] > expression_chain[3];

        float_instruction %= (float_instr[0] | float_instr[1] | float_instr[2] | float_instr[3]) > end_of_statement;

        // Error handling
        BOOST_SPIRIT_DEBUG_NODE(opcode[0]);
        BOOST_SPIRIT_DEBUG_NODE(opcode[1]);
        BOOST_SPIRIT_DEBUG_NODE(opcode[2]);
        BOOST_SPIRIT_DEBUG_NODE(opcode[3]);

        BOOST_SPIRIT_DEBUG_NODE(expression_chain[0]);
        BOOST_SPIRIT_DEBUG_NODE(expression_chain[1]);
        BOOST_SPIRIT_DEBUG_NODE(expression_chain[2]);
        BOOST_SPIRIT_DEBUG_NODE(expression_chain[3]);

        BOOST_SPIRIT_DEBUG_NODE(float_instr[0]);
        BOOST_SPIRIT_DEBUG_NODE(float_instr[1]);
        BOOST_SPIRIT_DEBUG_NODE(float_instr[2]);
        BOOST_SPIRIT_DEBUG_NODE(float_instr[3]);
        BOOST_SPIRIT_DEBUG_NODE(float_instruction);

        diagnostics.Add(expression_chain[0].name(), "one argument");
        diagnostics.Add(expression_chain[1].name(), "two arguments");
        diagnostics.Add(expression_chain[2].name(), "three arguments");
        diagnostics.Add(expression_chain[3].name(), "four arguments");

        qi::on_error<qi::fail>(float_instruction, error_handler(phoenix::ref(diagnostics), _1, _2, _3, _4));
}


text:
// Copyright 2014 The CRAVE developers. All rights reserved.//
#pragma once

#include <boost/intrusive_ptr.hpp>

#include <ostream>
#include <set>

#include <stdint.h>

#include "visitor/NodeVisitor.hpp"

namespace crave {

class Node;

typedef boost::intrusive_ptr<Node> NodePtr;

class Node {
 protected:
  Node() : count_(0) {}
  virtual ~Node() {}
  Node(Node const& n) : count_(0) {}

 public:
  virtual void visit(NodeVisitor* v) const { v->visitNode(*this); }
  std::ostream& printDot(std::ostream& out) const;

  // reference counting
  friend inline void intrusive_ptr_add_ref(Node* n) { ++(n->count_); }
  friend inline void intrusive_ptr_release(Node* n) {
    if (--(n->count_) == 0) delete n;
  }

 private:
  unsigned int count_;
};

class Placeholder : public Node {
 public:
  explicit Placeholder(unsigned int id) : Node(), id_(id) {}
  Placeholder(Placeholder const& p) : Node(p), id_(p.id()) {}

  void visit(NodeVisitor* v) const { v->visitPlaceholder(*this); }

  unsigned int id() const { return id_; }

 private:
  unsigned int id_;
};

class Terminal : public Node {
 protected:
  Terminal(unsigned int bs, bool s) : Node(), bitsize_(bs), sign_(s) {}
  Terminal(Terminal const& t) : Node(t), bitsize_(t.bitsize()), sign_(t.sign()) {}

 public:
  virtual void visit(NodeVisitor* v) const { v->visitTerminal(*this); }

  unsigned int bitsize() const { return bitsize_; }
  bool sign() const { return sign_; }
  bool isBool() const { return bitsize() == 1 && sign(); }

 private:
  unsigned int bitsize_;
  bool sign_;
};

class VariableExpr : public Terminal {
 public:
  VariableExpr(unsigned int id, unsigned int bs, bool s) : Terminal(bs, s), id_(id) {}
  VariableExpr(VariableExpr const& v) : Terminal(v.bitsize(), v.sign()), id_(v.id()) {}

  void visit(NodeVisitor* v) const { v->visitVariableExpr(*this); }

  unsigned int id() const { return id_; }

 private:
  unsigned int id_;
};

class Constant : public Terminal {
 public:
  Constant() : Terminal(1, true), value_(false) {}
  Constant(uint64_t val, unsigned int bs, bool s) : Terminal(bs, s), value_(val) {}
  explicit Constant(bool b) : Terminal(1, true), value_(b) {}
  Constant(Constant const& c) : Terminal(c.bitsize(), c.sign()), value_(c.value()) {}

  void visit(NodeVisitor* v) const { v->visitConstant(*this); }

  operator uint64_t() const { return value_; }

  uint64_t value() const { return value_; }

 private:
  uint64_t value_;
};

class VectorExpr : public Terminal {
 public:
  VectorExpr(unsigned int id, unsigned int bs, bool s) : Terminal(bs, s), id_(id) {}
  VectorExpr(VectorExpr const& v) : Terminal(v.bitsize(), v.sign()), id_(v.id()) {}

  void visit(NodeVisitor* v) const { v->visitVectorExpr(*this); }

  unsigned int id() const { return id_; }

 private:
  unsigned int id_;
};

class UnaryExpression : public Node {
 protected:
  explicit UnaryExpression(NodePtr c) : Node(), child_(c) {}
  UnaryExpression(UnaryExpression const& u) : Node(), child_() { child_.operator=(u.child().get()); }

 public:
  virtual void visit(NodeVisitor* v) const { v->visitUnaryExpr(*this); }

  NodePtr child() const { return child_; }

 private:
  NodePtr child_;
};

class UnaryOperator : public UnaryExpression {
 protected:
  explicit UnaryOperator(NodePtr c) : UnaryExpression(c) {}
  UnaryOperator(UnaryOperator const& u) : UnaryExpression(u) {}

 public:
  virtual void visit(NodeVisitor* v) const { v->visitUnaryOpr(*this); }
};

class NotOpr : public UnaryOperator {
 public:
  explicit NotOpr(NodePtr c) : UnaryOperator(c) {}
  NotOpr(NotOpr const& n) : UnaryOperator(n) {}

  void visit(NodeVisitor* v) const { v->visitNotOpr(*this); }
};

class NegOpr : public UnaryOperator {
 public:
  explicit NegOpr(NodePtr c) : UnaryOperator(c) {}
  NegOpr(NegOpr const& n) : UnaryOperator(n) {}

  void visit(NodeVisitor* v) const { v->visitNegOpr(*this); }
};

class ComplementOpr : public UnaryOperator {
 public:
  explicit ComplementOpr(NodePtr c) : UnaryOperator(c) {}
  ComplementOpr(ComplementOpr const& n) : UnaryOperator(n) {}

  void visit(NodeVisitor* v) const { v->visitComplementOpr(*this); }
};

class Inside : public UnaryExpression {
 public:
  Inside(NodePtr v, std::set<Constant> const& c) : UnaryExpression(v), collection_(c) {}
  Inside(Inside const& i) : UnaryExpression(i), collection_(i.collection()) {}

  void visit(NodeVisitor* v) const { v->visitInside(*this); }

  std::set<Constant> const& collection() const { return collection_; }

 private:
  std::set<Constant> collection_;
};

class ExtendExpression : public UnaryExpression {
 public:
  ExtendExpression(NodePtr v, unsigned int i) : UnaryExpression(v), value_(i) {}
  ExtendExpression(ExtendExpression const& e) : UnaryExpression(e), value_(e.value()) {}

  void visit(NodeVisitor* v) const { v->visitExtendExpr(*this); }

  unsigned int const& value() const { return value_; }

 private:
  unsigned int value_;
};

class BinaryExpression : public Node {
 protected:
  BinaryExpression(NodePtr lhs, NodePtr rhs) : lhs_(lhs), rhs_(rhs) {}
  BinaryExpression(BinaryExpression const& b) : Node(), lhs_(), rhs_() {
    lhs_.operator=(b.lhs().get());
    rhs_.operator=(b.rhs().get());
  }

 public:
  virtual void visit(NodeVisitor* v) const { v->visitBinaryExpr(*this); }

  NodePtr lhs() const { return lhs_; }
  NodePtr rhs() const { return rhs_; }

 private:
  NodePtr lhs_;
  NodePtr rhs_;
};

class BinaryOperator : public BinaryExpression {
 protected:
  BinaryOperator(NodePtr lhs, NodePtr rhs) : BinaryExpression(lhs, rhs) {}
  BinaryOperator(BinaryOperator const& b) : BinaryExpression(b) {}

 public:
  virtual void visit(NodeVisitor* v) const { v->visitBinaryOpr(*this); }
};

class AndOpr : public BinaryOperator {
 public:
  AndOpr(NodePtr lhs, NodePtr rhs) : BinaryOperator(lhs, rhs) {}
  AndOpr(AndOpr const& a) : BinaryOperator(a) {}

  void visit(NodeVisitor* v) const { v->visitAndOpr(*this); }
};

class OrOpr : public BinaryOperator {
 public:
  OrOpr(NodePtr lhs, NodePtr rhs) : BinaryOperator(lhs, rhs) {}
  OrOpr(OrOpr const& o) : BinaryOperator(o) {}

  void visit(NodeVisitor* v) const { v->visitOrOpr(*this); }
};

class LogicalAndOpr : public BinaryOperator {
 public:
  LogicalAndOpr(NodePtr lhs, NodePtr rhs) : BinaryOperator(lhs, rhs) {}
  LogicalAndOpr(LogicalAndOpr const& a) : BinaryOperator(a) {}

  void visit(NodeVisitor* v) const { v->visitLogicalAndOpr(*this); }
};

class LogicalOrOpr : public BinaryOperator {
 public:
  LogicalOrOpr(NodePtr lhs, NodePtr rhs) : BinaryOperator(lhs, rhs) {}
  LogicalOrOpr(LogicalOrOpr const& o) : BinaryOperator(o) {}

  void visit(NodeVisitor* v) const { v->visitLogicalOrOpr(*this); }
};

class XorOpr : public BinaryOperator {
 public:
  XorOpr(NodePtr lhs, NodePtr rhs) : BinaryOperator(lhs, rhs) {}
  XorOpr(XorOpr const& x) : BinaryOperator(x) {}

  void visit(NodeVisitor* v) const { v->visitXorOpr(*this); }
};

class EqualOpr : public BinaryOperator {
 public:
  EqualOpr(NodePtr lhs, NodePtr rhs) : BinaryOperator(lhs, rhs) {}
  EqualOpr(EqualOpr const& e) : BinaryOperator(e) {}

  void visit(NodeVisitor* v) const { v->visitEqualOpr(*this); }
};

class NotEqualOpr : public BinaryOperator {
 public:
  NotEqualOpr(NodePtr lhs, NodePtr rhs) : BinaryOperator(lhs, rhs) {}
  NotEqualOpr(NotEqualOpr const& n) : BinaryOperator(n) {}

  void visit(NodeVisitor* v) const { v->visitNotEqualOpr(*this); }
};

class LessOpr : public BinaryOperator {
 public:
  LessOpr(NodePtr lhs, NodePtr rhs) : BinaryOperator(lhs, rhs) {}
  LessOpr(LessOpr const& l) : BinaryOperator(l) {}

  void visit(NodeVisitor* v) const { v->visitLessOpr(*this); }
};

class LessEqualOpr : public BinaryOperator {
 public:
  LessEqualOpr(NodePtr lhs, NodePtr rhs) : BinaryOperator(lhs, rhs) {}
  LessEqualOpr(LessEqualOpr const& l) : BinaryOperator(l) {}

  void visit(NodeVisitor* v) const { v->visitLessEqualOpr(*this); }
};

class GreaterOpr : public BinaryOperator {
 public:
  GreaterOpr(NodePtr lhs, NodePtr rhs) : BinaryOperator(lhs, rhs) {}
  GreaterOpr(GreaterOpr const& g) : BinaryOperator(g) {}

  void visit(NodeVisitor* v) const { v->visitGreaterOpr(*this); }
};

class GreaterEqualOpr : public BinaryOperator {
 public:
  GreaterEqualOpr(NodePtr lhs, NodePtr rhs) : BinaryOperator(lhs, rhs) {}
  GreaterEqualOpr(GreaterEqualOpr const& g) : BinaryOperator(g) {}

  void visit(NodeVisitor* v) const { v->visitGreaterEqualOpr(*this); }
};

class PlusOpr : public BinaryOperator {
 public:
  PlusOpr(NodePtr lhs, NodePtr rhs) : BinaryOperator(lhs, rhs) {}
  PlusOpr(PlusOpr const& p) : BinaryOperator(p) {}

  void visit(NodeVisitor* v) const { v->visitPlusOpr(*this); }
};

class MinusOpr : public BinaryOperator {
 public:
  MinusOpr(NodePtr lhs, NodePtr rhs) : BinaryOperator(lhs, rhs) {}
  MinusOpr(MinusOpr const& m) : BinaryOperator(m) {}

  void visit(NodeVisitor* v) const { v->visitMinusOpr(*this); }
};

class MultipliesOpr : public BinaryOperator {
 public:
  MultipliesOpr(NodePtr lhs, NodePtr rhs) : BinaryOperator(lhs, rhs) {}
  MultipliesOpr(MultipliesOpr const& m) : BinaryOperator(m) {}

  void visit(NodeVisitor* v) const { v->visitMultipliesOpr(*this); }
};

class DevideOpr : public BinaryOperator {
 public:
  DevideOpr(NodePtr lhs, NodePtr rhs) : BinaryOperator(lhs, rhs) {}
  DevideOpr(DevideOpr const& d) : BinaryOperator(d) {}

  void visit(NodeVisitor* v) const { v->visitDevideOpr(*this); }
};

class ModuloOpr : public BinaryOperator {
 public:
  ModuloOpr(NodePtr lhs, NodePtr rhs) : BinaryOperator(lhs, rhs) {}
  ModuloOpr(ModuloOpr const& m) : BinaryOperator(m) {}

  void visit(NodeVisitor* v) const { v->visitModuloOpr(*this); }
};

class ShiftLeftOpr : public BinaryOperator {
 public:
  ShiftLeftOpr(NodePtr lhs, NodePtr rhs) : BinaryOperator(lhs, rhs) {}
  ShiftLeftOpr(ShiftLeftOpr const& s) : BinaryOperator(s) {}

  void visit(NodeVisitor* v) const { v->visitShiftLeftOpr(*this); }
};

class ShiftRightOpr : public BinaryOperator {
 public:
  ShiftRightOpr(NodePtr lhs, NodePtr rhs) : BinaryOperator(lhs, rhs) {}
  ShiftRightOpr(ShiftRightOpr const& s) : BinaryOperator(s) {}

  void visit(NodeVisitor* v) const { v->visitShiftRightOpr(*this); }
};

class VectorAccess : public BinaryExpression {
 public:
  VectorAccess(NodePtr lhs, NodePtr rhs) : BinaryExpression(lhs, rhs) {}
  VectorAccess(VectorAccess const& v) : BinaryExpression(v) {}

  void visit(NodeVisitor* v) const { v->visitVectorAccess(*this); }
};

class TernaryExpression : public Node {
 protected:
  explicit TernaryExpression(NodePtr a, NodePtr b, NodePtr c) : Node(), a_(a), b_(b), c_(c) {}
  TernaryExpression(TernaryExpression const& t) : Node(t), a_(), b_(), c_() {
    a_.operator=(t.a().get());
    b_.operator=(t.b().get());
    c_.operator=(t.c().get());
  }

 public:
  virtual void visit(NodeVisitor* v) const { v->visitTernaryExpr(*this); }

  NodePtr a() const { return a_; }
  NodePtr b() const { return b_; }
  NodePtr c() const { return c_; }

 private:
  NodePtr a_;
  NodePtr b_;
  NodePtr c_;
};

class IfThenElse : public TernaryExpression {
 public:
  IfThenElse(NodePtr a, NodePtr b, NodePtr c) : TernaryExpression(a, b, c) {}
  IfThenElse(IfThenElse const& t) : TernaryExpression(t) {}

  void visit(NodeVisitor* v) const { v->visitIfThenElse(*this); }
};

class ForEach : public BinaryOperator {
 public:
  ForEach(NodePtr a, NodePtr b) : BinaryOperator(a, b) {}
  ForEach(ForEach const& fe) : BinaryOperator(fe) {}

  void visit(NodeVisitor* v) const { v->visitForEach(*this); }
};

class Unique : public UnaryOperator {
 public:
  explicit Unique(NodePtr a) : UnaryOperator(a) {}
  Unique(Unique const& u) : UnaryOperator(u) {}

  void visit(NodeVisitor* v) const { v->visitUnique(*this); }
};

class Bitslice : public UnaryExpression {
 public:
  Bitslice(NodePtr v, int r, int l) : UnaryExpression(v), r_(r), l_(l) {}

  Bitslice(Bitslice const& b) : UnaryExpression(b), r_(b.r_), l_(b.l_) {}

  void visit(NodeVisitor* v) const { v->visitBitslice(*this); }

  int r() const { return r_; }
  int l() const { return l_; }

 private:
  int r_, l_;
};

}  // end namespace crave