text:
#include <stdlib.h>
#include <unistd.h>
#include <sstream>
#include <iostream>
#include <boost/thread.hpp>
#include "../common/mydb.h"
#include "../common/mycache.h"
#include "../common/mylogger.h"

static LoggerPtr logger(Logger::getLogger("mycache-test"));

static int s_interrupted = 0;

static void s_signal_handler (int signal_value)
{
	LOG4CXX_INFO(logger, "catch the signal : " << signal_value);

    s_interrupted = 1;
}

static void s_catch_signals (void)
{
    struct sigaction action;
    action.sa_handler = s_signal_handler;
    action.sa_flags = 0;
    sigemptyset (&action.sa_mask);
    sigaction (SIGINT, &action, NULL);
    sigaction (SIGTERM, &action, NULL);
}

MyCacheClient mycache;

void test_set(int num, int size = 10)
{
	for (int i = 0; i < num; ++i)
	{
		std::string key = formatKey("user:%d", i);

		//std::ostringstream value;
		//value << "user ................... " << i;

		std::string value(size, 'A');
		if (mycache.set(key, value))
		{
			LOG4CXX_INFO(logger, "set " << key << " [OK]");
		}
		else
		{
			LOG4CXX_INFO(logger, "set " << key << " [FAILED]");
		}
	}
}

void test_get(int num)
{
	for (int i = 0; i < num; ++i)
	{
		std::string key = formatKey("user:%d", i);
		std::string value;

		if (mycache.get(key, value))
		{
			LOG4CXX_INFO(logger, key << "=" << value.size());
		}
		else
		{
			LOG4CXX_INFO(logger, "get " << key << " [FAILED]");
		}
	}
}

void test_del(int num)
{
	for (int i = 0; i < num; ++i)
	{
		std::string key = formatKey("user:%d", i);
		std::string value;

		if (mycache.del(key))
		{
			LOG4CXX_INFO(logger, "del " << key << " [OK]");
		}
		else
		{
			LOG4CXX_INFO(logger, "del " << key << " [FAILED]");
		}
	}
}

void test_thread(int num)
{
	#if 0
	MyCacheClient* cache = MyCachePool::instance()->acquire();
	if (cache)
	{
		LOG4CXX_INFO(logger, "do some thing:" << pthread_self());
		usleep(100);
		MyCachePool::instance()->putback(cache);
	}
	#endif

	#if 1
	for (int i = 0; i < num; ++i)
	{
		std::string key = formatKey("user:%d", i);
		std::string value;

		if (MyCache::get(key, value))
		{
			LOG4CXX_INFO(logger, key << "=" << value << ":" << pthread_self());
		}
		else
		{
			LOG4CXX_INFO(logger, "get " << key << " [FAILED]");
		}
	}
	#endif
}

void test_timer()
{
	MyCache::init("tcp://localhost:5555");
	while (!s_interrupted)
	{
		std::string reply;
		MyCache::get("user:1", reply);
		std::cout << reply << std::endl;
		sleep(1);
	}
}

void async_test_1(AsyncMyCacheClient* client)
{
	struct GetUser : public MyCache::Get
	{
		GetUser(const std::string& key) : MyCache::Get(key) {}

		virtual ~GetUser()
		{
			LOG4CXX_INFO(logger, id << " key1: deleted");
		}

		virtual void replied(const std::string& reply)
		{
			struct GetUser2 : public MyCache::Get
			{
				GetUser2(const std::string& key) :MyCache::Get(key) {}

				virtual ~GetUser2()
				{
					LOG4CXX_INFO(logger, id << " key2: deleted");
				}

				virtual void replied(const std::string& reply)
				{
					MyCache::Get::replied(reply);

					if (context)
					{
						LOG4CXX_INFO(logger, "serials: "
							<< context->get<int>("worker") << ","
							<< context->get<std::string>("user:1") << ","
							<< context->get<std::string>("user:2"));
					}
					else
					{
						LOG4CXX_INFO(logger, "serials: no context");
					}
				}
			};

			LOG4CXX_INFO(logger, id << ":" <<  key << "=" << reply);
			MyCache::Get::replied(reply);

			client->call(new GetUser2("user:2"), context, 2000);
		}

		virtual void timeouted()
		{
			LOG4CXX_INFO(logger, id << ":" << key << "= ... timeout");
		}
	};

	ContextPtr c(new Context());
	c->set("worker", 1);
	client->call(new GetUser("user:1"), c, 2000);
	//client->call(new GetUser("user:1"), ContextPtr(), 2000);
}

void async_test_2(AsyncMyCacheClient* client)
{

	struct Done : public SerialsCallBack
	{
		virtual void called(void*)
		{
			LOG4CXX_INFO(logger, "serials: "
							<< context->get<int>("top") << ","
							<< context->get<std::string>("user:1") << ","
							<< context->get<std::string>("user:2") << ","
							<< context->get<std::string>("user:3") << ","
							);
		}
	};

	ContextPtr c(new Context);
	c->set("top", 2);

	client->callBySerials(new Done,
		AsyncRPC::S(
			new MyCache::Get("user:1"),
			new MyCache::Get("user:2"),
			new MyCache::Get("user:3"),
			NULL),
		c, -1);
}

void async_test_3(AsyncMyCacheClient* client)
{

	struct Done : public ParallelCallBack
	{
		virtual void called(void*)
		{
			LOG4CXX_INFO(logger, "parallel: "
							<< context->get<int>("top") << ","
							<< context->get<std::string>("user:1") << ","
							<< context->get<std::string>("user:2") << ","
							<< context->get<std::string>("user:3") << ","
							);
		}
	};

	ContextPtr c(new Context);
	c->set("top", 2);

#if 0
	client->callByParallel(new Done,
		AsyncRPC::S(
			new MyCache::Get("user:1"),
			new MyCache::Get("user:2"),
			new MyCache::Get("user:3"),
			NULL),
		c, -1);
#else
	client->callByParallel(new Done, c,
		new MyCache::Get("user:1"),
		new MyCache::Get("user:2"),
		NULL);
#endif
}

void async_worker(AsyncMyCacheClient* client)
{
	while (!s_interrupted)
	{
		//async_test_1(client);
		//async_test_2(client);
		async_test_3(client);

		sleep(1);
		//break;
	}
}

void test_sharedptr()
{
	ContextPtr c(new Context);
	c->set("key1", "david");
	c->set("key2", 1);
	std::cout << c->debugString() << std::endl;

	{
	ContextPtr c2 = c;
	std::cout << c.use_count() << std::endl;
	}
	std::cout << c.use_count() << std::endl;

	return;
}

void test_async(int num)
{
	AsyncMyCacheClient async("test");

	if (!async.connect("tcp://localhost:5555"))
		return;

	boost::thread_group thrds;
	for (int i = 0; i < num ; i++)
		thrds.create_thread(boost::bind(async_worker, &async));

	while (!s_interrupted)
	{
		try
		{
			async.loop();

			//std::cout << async.scheduler().stat().debugString() << std::endl;
        }
		catch (std::exception& err)
		{
			std::cout << "!!!!" << err.what() << std::endl;
		}
	}

	thrds.join_all();
}

int main(int argc, const char* argv[])
{
	s_catch_signals();
	BasicConfigurator::configure();

	mycache.connect("tcp://localhost:5555");

	if (argc > 1)
	{
		int num = 1;
		if (argc > 2)
			num = atol(argv[2]);

		int size = 10;
		if (argc > 3)
			size = atol(argv[3]);

		std::string arg1 = argv[1];
		if ("set" == arg1)
		{
			test_set(num, size);
		}
		else if("get" == arg1)
		{
			test_get(num);
		}
		else if ("del" == arg1)
		{
			test_del(num);
		}
		else if ("thread" == arg1)
		{
			//MyCachePool::instance()->setServerAddress("tcp://localhost:5555");
			//MyCachePool::instance()->setMaxConn(5);
			//MyCachePool::instance()->createAll();
			MyCache::init("tcp://localhost:5555", 5);

			boost::thread_group thrds;

			for (int i = 0; i < num; i++)
				thrds.create_thread(boost::bind(test_thread, 100));

			thrds.join_all();
		}
		else if ("timer" == arg1)
		{
			test_timer();
		}
		else if ("async" == arg1)
		{
			test_async(num);
		}

		return 0;
	}

}

ext: cpp

max_stars_repo_name: david-pp/tinyworld

max_issues_repo_name: david-pp/tinyworld-servers

max_forks_repo_name: david-pp/tinyworld-servers


text:
#include <iostream>
#include <string>

#include <boost/python.hpp>

struct hello_world
{
    void say_hello() { std::cout << "Hello world!" << std::endl; }
};

using namespace boost::python;

BOOST_PYTHON_MODULE(janucaria)
{
	class_< hello_world >("HelloWorld")
	  .def("say_hello", &hello_world::say_hello);
}

max_stars_repo_name: janucaria/cpp-boost-python-example

max_issues_repo_name: janucaria/cpp-boost-python-example

max_forks_repo_name: janucaria/cpp-boost-python-example


text:
#include <iostream>
#include <boost/uuid/uuid.hpp>            // uuid class
#include <boost/uuid/uuid_generators.hpp> // generators
#include <boost/uuid/uuid_io.hpp>         // streaming operators etc.
#include <sstream>
#include <openssl/sha.h>
#include <iomanip>

using namespace std;

string sha256(const string str)
{
    unsigned char hash[SHA256_DIGEST_LENGTH];
    SHA256_CTX sha256;
    SHA256_Init(&sha256);
    SHA256_Update(&sha256, str.c_str(), str.size());
    SHA256_Final(hash, &sha256);
    stringstream ss;
    for(int i = 0; i < SHA256_DIGEST_LENGTH; i++)
    {
        ss << hex << setw(2) << setfill('0') << (int)hash[i];
    }
    return ss.str();
}

int main() {
    boost::uuids::uuid uuid = boost::uuids::random_generator()();
    cout << uuid << endl;
    cout << sha256("password") << endl;
 }

max_stars_repo_name: rambasnet/EthicalHacking-Notebooks

max_issues_repo_name: rambasnet/EthicalHacking-Notebooks

max_forks_repo_name: rambasnet/EthicalHacking-Notebooks


text:
#include "sgf_parser.h"

#include <iostream>
#include <iomanip>

#define BOOST_SPIRIT_DEBUG
#define BOOST_SPIRIT_QI_DEBUG
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/classic_core.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_fusion.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_fusion.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
#include <boost/spirit/include/support_multi_pass.hpp>
#include <boost/fusion/include/std_pair.hpp>
#include <boost/bind.hpp>
#include <fstream>
//#include <boost/spirit/include/classic_debug.hpp>
//#include <boost/spirit/include/classic_debug_node.hpp>
#include "Sgf.h"
#include "move.h"
#include "../src/logutils.h"

namespace qi = boost::spirit::qi;

BOOST_FUSION_ADAPT_STRUCT(
    Property,
    (std::string, identifier)
    (PropValueList, values)
)

BOOST_FUSION_ADAPT_STRUCT(
    GameTree,
    (std::vector<Node>, sequence_)
    (std::vector<GameTree>, sub_trees)
)

template <typename InputIterator>
struct sgf_parser : public boost::spirit::qi::grammar<InputIterator, GameTree()> {
    sgf_parser() : sgf_parser::base_type(game_tree) {
//         point = (qi::alpha | qi::upper) >> (qi::alpha | qi::upper);
//         color = qi::char_('B') | qi::char_('W');
//         value_type = (qi::int_ | qi::double_ | point | color | *(qi::char_ - ']'));
        using boost::spirit::_val;
        using boost::spirit::_1;
        using boost::spirit::_2;
        using boost::phoenix::at_c;
        using boost::phoenix::push_back;
        escChar = '\\' >> qi::char_("\\[]:");
        value_type = *(~qi::char_("\\]") | escChar) [_val += _1];
        compose = value_type >> ':' >> value_type;
        c_value_type = value_type | compose;
        prop_value = '[' >> c_value_type [_val = _1] >> ']' >> *qi::space;
        prop_ident = +qi::upper [_val += _1];
        property = *qi::space >> prop_ident [at_c<0>(_val) = _1] >> +prop_value [push_back(at_c<1>(_val), _1)];
        node = ';' >> +property;
        sequence = +node [push_back(_val, _1)] >> *qi::space;
        game_tree = '(' >> *qi::space >> sequence [at_c<0>(_val) = _1] >> *game_tree [push_back(at_c<1>(_val), _1)] >> ')' >> *qi::space;
    }

    qi::rule<InputIterator, char()> escChar;
    qi::rule<InputIterator, GameTree()> single_tree, game_tree;
    qi::rule<InputIterator, Sequence()> sequence;
    qi::rule<InputIterator, Node()> node;
    qi::rule<InputIterator, Property()> property;
    qi::rule<InputIterator, Compose()> compose;
    qi::rule<InputIterator, std::string()> value_type, prop_ident;
    qi::rule<InputIterator, std::variant<std::string, Compose>()> c_value_type, prop_value;

};

GameTree parse_sgf(const std::string& filename) {
    std::ifstream sgf_file(filename);
    sgf_file.unsetf(std::ios::skipws);

    using base_it_t = boost::spirit::istream_iterator;
    using fwd_it_t = boost::spirit::multi_pass<base_it_t>;
    base_it_t begin(sgf_file);
    base_it_t end;
    sgf_parser<base_it_t> sgf_parser;
    GameTree ast;
    bool r = qi::parse(begin,
                       end,
                       sgf_parser, ast);
//    print_game_tree(ast);
    //auto move = parse_game_tree(ast);
    //std::cout << r << std::endl;
    return ast;
}

max_stars_repo_name: mkkelley/autogrp

max_issues_repo_name: mkkelley/autogrp

max_forks_repo_name: mkkelley/autogrp


text:
#include <boost/test/unit_test.hpp>

#include <dracosha/validator/value_transformer.hpp>
#include <dracosha/validator/validator.hpp>
#include <dracosha/validator/adapters/reporting_adapter.hpp>

using namespace DRACOSHA_VALIDATOR_NAMESPACE;

BOOST_AUTO_TEST_SUITE(TestValueTransformer)

namespace
{
    size_t h1(const std::string& val) noexcept
    {
        return val.size();
    }
    bool h2(const std::string& val) noexcept
    {
        return val.empty();
    }
}

BOOST_AUTO_TEST_CASE(CheckTransformer)
{
    auto t1=make_value_transformer(h1,"value size");

    static_assert(decltype(t1)::has<std::string>(),"");
    static_assert(!decltype(t1)::has<int>(),"");

    std::string s1("Hello world");
    BOOST_CHECK_EQUAL(t1.get(s1),s1.size());
    BOOST_CHECK_EQUAL(property(s1,t1),s1.size());

    BOOST_CHECK_EQUAL(t1.name(),std::string("value size"));
}

BOOST_AUTO_TEST_CASE(CheckValidateTransformer)
{
    auto t1=make_value_transformer(h1,"value size");

    auto check=[](auto&& v1, auto property_notation)
    {
        std::string s1("Hello world");
        BOOST_CHECK(v1.apply(s1));

        std::string s2("Hi");
        BOOST_CHECK(!v1.apply(s2));

        hana::eval_if
        (
            property_notation,
            [&](auto&&)
            {},
            [&](auto&& _)
            {
                int i3=100;
                BOOST_CHECK(_(v1).apply(i3)); // ignored

                auto a4=make_default_adapter(i3);
                a4.set_check_member_exists_before_validation(true);
                a4.set_unknown_member_mode(if_member_not_found::abort);
                BOOST_CHECK(!_(v1).apply(a4));
            }
        );
    };

    BOOST_TEST_CONTEXT("member notation")
    {
        auto v1=validator(
                _[t1](gte,5)
            );
        check(v1,std::false_type{});
    }

    BOOST_TEST_CONTEXT("property notation")
    {
        auto v2=validator(
                t1(gte,5)
            );
        check(v2,std::true_type{});
    }
}

BOOST_AUTO_TEST_CASE(CheckValidateTransformerReport)
{
    auto t1=make_value_transformer(h1,"value size");

    auto check=[](auto&& v1, auto property_notation)
    {
        std::string rep;
        std::string s2("Hi");
        auto a2=make_reporting_adapter(s2,rep);
        BOOST_CHECK(!v1.apply(a2));
        BOOST_CHECK_EQUAL(rep,std::string("value size must be greater than or equal to 5"));

        hana::eval_if
        (
            property_notation,
            [&](auto&&)
            {},
            [&](auto&& _)
            {
                std::string rep;
                int i3=100;
                auto a4=make_reporting_adapter(i3,rep);
                a4.set_check_member_exists_before_validation(true);
                a4.set_unknown_member_mode(if_member_not_found::abort);
                BOOST_CHECK(!_(v1).apply(a4));
                BOOST_CHECK_EQUAL(rep,std::string("value size must exist"));
            }
        );
    };

    BOOST_TEST_CONTEXT("member notation")
    {
        auto v1=validator(
                _[t1](gte,5)
            );
        check(v1,std::false_type{});
    }

    BOOST_TEST_CONTEXT("property notation")
    {
        auto v2=validator(
                t1(gte,5)
            );
        check(v2,std::true_type{});
    }
}

BOOST_AUTO_TEST_CASE(CheckValidateTransformerFlag)
{
    auto t1=make_value_transformer(h2,"content","must be empty","must not be empty");

    auto check1=[](auto&& v1)
    {
        std::string rep;
        std::string s2("Hi");
        auto a2=make_reporting_adapter(s2,rep);
        BOOST_CHECK(!v1.apply(a2));
        BOOST_CHECK_EQUAL(rep,std::string("must be empty"));
    };
    auto check2=[](auto&& v1)
    {
        std::string rep;
        std::string s2;
        auto a2=make_reporting_adapter(s2,rep);
        BOOST_CHECK(!v1.apply(a2));
        BOOST_CHECK_EQUAL(rep,std::string("must not be empty"));
    };

    BOOST_TEST_CONTEXT("member notation")
    {
        auto v1=validator(
                _[t1](flag,true)
            );
        check1(v1);
        auto v2=validator(
                _[t1](flag,false)
            );
        check2(v2);
    }
    BOOST_TEST_CONTEXT("property notation")
    {
        auto v1=validator(
                t1(flag,true)
            );
        check1(v1);
        auto v2=validator(
                t1(flag,false)
            );
        check2(v2);
    }
}

BOOST_AUTO_TEST_SUITE_END()

max_stars_repo_name: evgeniums/cpp-validator

max_issues_repo_name: evgeniums/cpp-validator

max_forks_repo_name: evgeniums/cpp-validator


text:
#include <boost/test/unit_test.hpp>

#include <vm/messages.hpp>
#include <vm/tools.hpp>
#include <vm/vm.hpp>

#include <filesystem>
#include <iostream>
#include <map>

class HostImplementation : public evmc::Host
{
    std::map<evmc::bytes32, evmc::bytes32> _storage;

  public:
    ~HostImplementation() noexcept override = default;

    bool account_exists(const evmc::address& addr) const noexcept override
    {
        std::cout << "account_exists method call: address[ " << vm::toBytes(addr) << "].\n";
        return false;
    }

    evmc::bytes32 get_storage(const evmc::address& addr, const evmc::bytes32& key) const noexcept override
    {
        std::cout << "get_storage method call: address[" << vm::toBytes(addr) << "], key[" << vm::toBytes(key)
                  << "].\n";
        auto it = _storage.find(key);
        if (it != _storage.end()) {
            auto val = it->second;
            return val;
        }
        return evmc::bytes32();
    }

    evmc_storage_status set_storage(const evmc::address& addr,
                                    const evmc::bytes32& key,
                                    const evmc::bytes32& value) noexcept override
    {
        std::cout << "set_storage method call: address[" << base::toHex(vm::toBytes(addr)) << "], key["
                  << vm::toBytes(key) << "], value[" << vm::toBytes(value) << "].\n";
        auto f = _storage.find(key);
        if (f != _storage.end()) {
            f->second = value;
            return evmc_storage_status::EVMC_STORAGE_MODIFIED;
        }

        _storage.insert({ key, value });
        return evmc_storage_status::EVMC_STORAGE_ADDED;
    }

    evmc::uint256be get_balance(const evmc::address& addr) const noexcept override
    {
        std::cout << "get_balance method call: address[" << vm::toBytes(addr) << "].\n";
        return evmc::uint256be();
    }

    size_t get_code_size(const evmc::address& addr) const noexcept override
    {
        std::cout << "get_code_size method call: address: " << vm::toBytes(addr) << "].\n";
        return 0;
    }

    evmc::bytes32 get_code_hash(const evmc::address& addr) const noexcept override
    {
        std::cout << "get_code_hash call method call: " << vm::toBytes(addr) << "].\n";
        return evmc::bytes32();
    }

    size_t copy_code(const evmc::address& addr, size_t code_offset, uint8_t* buffer_data, size_t buffer_size) const
      noexcept override
    {
        std::cout << "copy_code call method call: " << vm::toBytes(addr)
                  << ", code_offset: " << std::to_string(code_offset)
                  << ", buffer_size: " << std::to_string(buffer_size) << "].\n";
        return 0;
    }

    void selfdestruct(const evmc::address& addr, const evmc::address& beneficiary) noexcept override
    {
        std::cout << "selfdestruct method call: address[" << vm::toBytes(addr) << "], beneficiary["
                  << vm::toBytes(beneficiary) << "].\n";
    }

    evmc::result call(const evmc_message& msg) noexcept override
    {
        std::cout << "call method call: snd[" << vm::toBytes(msg.sender) << "], dest[" << vm::toBytes(msg.destination)
                  << "].\n";
        evmc::result res{ evmc_status_code::EVMC_SUCCESS, 0, nullptr, 0 };
        return res;
    }

    evmc_tx_context get_tx_context() const noexcept override
    {
        std::cout << "get_tx_context method call \n";
        return evmc_tx_context();
    }

    evmc::bytes32 get_block_hash(int64_t block_number) const noexcept override
    {
        std::cout << "get_block_hash method call: block_number[" << std::to_string(block_number) << "].\n";
        return evmc::bytes32();
    }

    void emit_log(const evmc::address& addr,
                  const uint8_t* data,
                  size_t data_size,
                  const evmc::bytes32 topics[],
                  size_t num_topics) noexcept override
    {
        std::cout << "emit_log method call: address[" << vm::toBytes(addr) << "], topics_number["
                  << std::to_string(num_topics) << "].\n";
    }
};

BOOST_AUTO_TEST_CASE(vm_base)
{
    const char* source_code = R"V0G0N(
pragma solidity >=0.4.16 <0.7.0;

contract Foo {
    uint32 public _x;

    constructor(uint32 x) public payable{
        _x = x;
    }

    function bar(uint32 x) public {
        _x = x;
    }

    function baz(uint32 x, bool y) public pure returns (bool r) {r = x > 32 || y;}

    function sam(bytes memory, bool, uint[] memory) public pure {}
}
)V0G0N";

    std::filesystem::path code_file_path = "vm_base.sol";

    std::ofstream file_descriptor(code_file_path);
    file_descriptor << source_code;
    file_descriptor.close();

    HostImplementation host{};
    auto vm_instance = vm::Vm::load(host);

    vm::Solc solc;

    auto contracts = solc.compile(code_file_path.string());
    if (!contracts) {
        BOOST_CHECK(false);
    }

    auto target_contract = contracts->front();
    for (const auto& sign : target_contract.getSignatures()) {
        std::cout << base::toHex(sign.first) << " | " << sign.second << std::endl;
    }

    auto target_code = target_contract.getFullCode();
    //////////////////////////////////////////////////

    auto source = base::fromHex<base::Bytes>("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaf");
    auto destination = base::fromHex<base::Bytes>("ffffffffffffffffffffffffffffffffffffaaff");

    vm::SmartContract contract{ target_code };

    auto target_value_1 = 1u;
    auto init_message = contract.createInitMessage(
      100000, bc::Address{ source }, bc::Address{ destination }, 1, vm::encode(target_value_1));
    auto res1 = vm_instance.execute(init_message);
    BOOST_CHECK(res1.ok());

    auto input_for_message_1 = base::fromHex<base::Bytes>("29809703"); // TODO: remove
    auto message1 =
      contract.createMessage(10000, bc::Address{ source }, bc::Address{ destination }, 0, input_for_message_1);
    auto res2 = vm_instance.execute(message1);
    BOOST_CHECK(res2.ok());

    BOOST_CHECK_EQUAL(res2.toOutputData(), vm::encode(target_value_1));

    auto target_value_2 = 69u;

    auto input_for_message_2 = base::fromHex<base::Bytes>("bd70b447") + vm::encode(target_value_2);
    auto message2 =
      contract.createMessage(10000, bc::Address{ source }, bc::Address{ destination }, 0, input_for_message_2);
    auto res3 = vm_instance.execute(message2);
    BOOST_CHECK(res3.ok());

    auto input_for_message_3 = base::fromHex<base::Bytes>("29809703"); // TODO: remove
    auto message3 =
      contract.createMessage(10000, bc::Address{ source }, bc::Address{ destination }, 0, input_for_message_3);
    auto res4 = vm_instance.execute(message3);
    BOOST_CHECK(res3.ok());

    BOOST_CHECK_EQUAL(res4.toOutputData(), vm::encode(target_value_2));

    std::filesystem::remove(code_file_path);
}

BOOST_AUTO_TEST_CASE(vm_dynamic_params)
{
    const char* source_code = R"V0G0N(
pragma solidity >=0.4.16 <0.7.0;

contract Foo {

    string public message;

    constructor(string memory initMessage) public {
        message = initMessage;
    }

    function update(string memory newMessage) public {
        message = newMessage;
    }
}
    )V0G0N";

    std::filesystem::path code_file_path = "vm_dynamic_params.sol";

    std::ofstream file_descriptor(code_file_path);
    file_descriptor << source_code;
    file_descriptor.close();

    HostImplementation host{};
    auto vm_instance = vm::Vm::load(host);

    vm::Solc solc;

    auto contracts = solc.compile(code_file_path.string());
    if (!contracts) {
        BOOST_CHECK(false);
    }

    auto target_contract = contracts->front();
    for (const auto& sign : target_contract.getSignatures()) {
        std::cout << base::toHex<base::Bytes>(sign.first) << " | " << sign.second << std::endl;
    }

    auto target_code = target_contract.getFullCode();
    //////////////////////////////////////////////////

    auto source = base::fromHex<base::Bytes>("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaf");
    auto destination = base::fromHex<base::Bytes>("ffffffffffffffffffffffffffffffffffffaaff");

    vm::SmartContract contract{ target_code };

    std::string target_value_1 = "one";

    auto init_message = contract.createInitMessage(
      1000000, bc::Address{ source }, bc::Address{ destination }, 0, vm::encode(32u) + vm::encode(target_value_1));
    auto res1 = vm_instance.execute(init_message);
    BOOST_CHECK(res1.ok());

    auto message1 = contract.createMessage(
      1000000, bc::Address{ source }, bc::Address{ destination }, 0, base::fromHex<base::Bytes>("e21f37ce"));
    auto res2 = vm_instance.execute(message1);
    BOOST_CHECK(res2.ok());

    BOOST_CHECK_EQUAL(vm::getStringArg(0, res2.toOutputData()), target_value_1);

    std::string target_value_2 = "Hello, world";

    auto message2 =
      contract.createMessage(1000000,
                             bc::Address{ source },
                             bc::Address{ destination },
                             0,
                             base::fromHex<base::Bytes>("3d7403a3") + vm::encode(32u) + vm::encode(target_value_2));
    auto res3 = vm_instance.execute(message2);
    BOOST_CHECK(res3.ok());

    auto message3 = contract.createMessage(
      1000000, bc::Address{ source }, bc::Address{ destination }, 0, base::fromHex<base::Bytes>("e21f37ce"));
    auto res4 = vm_instance.execute(message3);
    BOOST_CHECK(res3.ok());

    BOOST_CHECK_EQUAL(vm::getStringArg(0, res4.toOutputData()), target_value_2);

    std::filesystem::remove(code_file_path);
}

max_stars_repo_name: heshu-by/likelib

max_issues_repo_name: heshu-by/likelib

max_forks_repo_name: heshu-by/likelib


text:
#include <boost/program_options.hpp>
#include <boost/range/algorithm/copy.hpp>
#include <boost/range/adaptor/transformed.hpp>
#include <boost/iterator/zip_iterator.hpp>
#include <srook/range/adaptor/copied.hpp>
#include <srook/algorithm/coding/zlib.hpp>
#include <srook/optional.hpp>
#include <srook/expected.hpp>
#include <vector>
#include <string>
#include <iostream>

class program_options {
public:
    program_options(int ac, const char* const* const av)
        : description_("Allowed options"), ac_(srook::move(ac)), av_(av)
    {
        description_.add_options()
            ("help,h", "help")
            ("compress,c", boost::program_options::value<int>()->default_value(6), "compressing")
            ("decompress,d", "uncompress files")
            ("in,i", boost::program_options::value<std::vector<std::string>>(), "set input files. if you not set this flags, it will read from stdin")
            ("out,o", boost::program_options::value<std::vector<std::string>>(), "set name of output. if you not set this flags, it will output the file that added suffix `_out`");
    }

    void store()
    {
        boost::program_options::store(boost::program_options::parse_command_line(ac_, av_, description_), vm_);
        boost::program_options::notify(vm_);
    }

    const boost::program_options::variable_value& operator[](const char* key) const
    SROOK_NOEXCEPT(srook::declval<boost::program_options::variables_map>()[const char*()])
    { return vm_[key]; }

    const boost::program_options::variables_map* operator->() const SROOK_NOEXCEPT_TRUE
    { return srook::addressof(vm_); }

    const boost::program_options::options_description& description() const SROOK_NOEXCEPT_TRUE
    { return description_; }

private:
    boost::program_options::options_description description_;
    boost::program_options::variables_map vm_;
    const int ac_;
    const char* const* const av_;
};

srook::optional<std::vector<std::string>> make_filelist(const char* key, const program_options& opt)
{
    if (opt->count(key)) return { opt[key].as<std::vector<std::string>>() };
    return {};
}

srook::algorithm::zlib::compress_level narrowing_level(int level)
{
    if (level > Z_BEST_COMPRESSION) return srook::algorithm::zlib::compress_level::best;
    if (level < Z_NO_COMPRESSION) return srook::algorithm::zlib::compress_level::none;
    return static_cast<srook::algorithm::zlib::compress_level>(level);
}

void cat_stream(std::istream& is, std::ostream& os)
{
    const std::streamsize buff_size = 1 << 16;
    auto buffer = std::make_unique<char[]>(buff_size);
    while (true) {
        is.read(buffer.get(), buff_size);
        std::streamsize c = is.gcount();
        if (!c) break;
        os.write(buffer.get(), c);
    }
}

void compress(int level, const std::vector<std::string>& in_file, const std::vector<std::string>& out_file)
{
    auto begin = boost::make_zip_iterator(boost::make_tuple(std::begin(in_file), std::begin(out_file)));
    auto end = boost::make_zip_iterator(boost::make_tuple(std::end(in_file), std::end(out_file)));
    std::for_each(begin, end, [&level](auto&& t) {
            srook::io::ifstream ifs(t.template get<0>());
            srook::algorithm::zlib::ofstream ofs(t.template get<1>(), narrowing_level(level));
            cat_stream(ifs, ofs);
    });
}

void compress(int level, const std::vector<std::string>& out_file)
{
    for (auto&& o : out_file) {
        srook::algorithm::zlib::ofstream ofs(srook::forward<SROOK_DECLTYPE(o)>(o), narrowing_level(level));
        cat_stream(std::cin, ofs);
    }
}

void compress(int level)
{
    srook::algorithm::zlib::ostream os(std::cout, narrowing_level(srook::move(level)));
    cat_stream(std::cin, os);
}

void decompress(const std::vector<std::string>& in_file, const std::vector<std::string>& out_file)
{
    auto begin = boost::make_zip_iterator(boost::make_tuple(std::begin(in_file), std::begin(out_file)));
    auto end = boost::make_zip_iterator(boost::make_tuple(std::end(in_file), std::end(out_file)));
    std::for_each(begin, end, [](auto&& t) {
            srook::algorithm::zlib::ifstream ifs(t.template get<0>());
            srook::io::ofstream ofs(t.template get<1>());
            cat_stream(ifs, ofs);
    });
}

std::vector<std::string> addsuffix_out(const std::vector<std::string>& s)
{
    std::vector<std::string> r = s | boost::adaptors::transformed([](const std::string& s){ return s + "_out"; }) | srook::range::adaptors::copied;
    return r;
}

int main(int ac, const char* const* const av) try
{
    program_options opt(srook::move(ac), av);
    opt.store();

    if (opt->count("help")) {
        std::cout << opt.description() << std::endl;
        return EXIT_SUCCESS;
    }

    srook::optional<std::vector<std::string>> in_file(make_filelist("in", opt)), out_file(make_filelist("out", opt));
    if (opt->count("compress")) {
        int lv = opt["compress"].as<int>();
        if (in_file && !out_file) {
            compress(srook::move(lv), srook::move(*in_file), addsuffix_out(*in_file));
        } else if (in_file && out_file) {
            compress(srook::move(lv), srook::move(in_file.value()), srook::move(out_file.value()));
        } else if (!in_file && out_file) {
            compress(srook::move(lv), srook::move(out_file.value()));
        } else {
            compress(srook::move(lv));
        }
    }

    if (opt->count("decompress")) {
        if (in_file && !out_file) {
            decompress(srook::move(*in_file), addsuffix_out(*in_file));
        } else if (in_file && out_file) {
            decompress(srook::move(*in_file), srook::move(*out_file));
        }
    }
} catch (const std::exception& ex) {
    std::cerr << ex.what() << std::endl;
}

max_stars_repo_name: falgon/srookCppLibraries

max_issues_repo_name: falgon/srookCppLibraries

max_forks_repo_name: falgon/srookCppLibraries


text: #include <boost/math/special_functions/ellint_rj.hpp>

ext: hpp

max_stars_repo_name: miathedev/BoostForArduino

max_issues_repo_name: miathedev/BoostForArduino

max_forks_repo_name: miathedev/BoostForArduino


text:
#include <Common/config.h>
#if USE_PROTOBUF

#include <cassert>
#include <optional>
#include <math.h>
#include <AggregateFunctions/IAggregateFunction.h>
#include <DataTypes/DataTypesDecimal.h>
#include <boost/numeric/conversion/cast.hpp>
#include <google/protobuf/descriptor.h> // Y_IGNORE
#include <google/protobuf/descriptor.pb.h> // Y_IGNORE
#include <IO/ReadHelpers.h>
#include <IO/WriteHelpers.h>
#include "ProtobufWriter.h"

namespace DB
{
namespace ErrorCodes
{
    extern const int NOT_IMPLEMENTED;
    extern const int NO_DATA_FOR_REQUIRED_PROTOBUF_FIELD;
    extern const int PROTOBUF_BAD_CAST;
    extern const int PROTOBUF_FIELD_NOT_REPEATED;
}

namespace
{
    constexpr size_t MAX_VARINT_SIZE = 10;
    constexpr size_t REPEATED_PACK_PADDING = 2 * MAX_VARINT_SIZE;
    constexpr size_t NESTED_MESSAGE_PADDING = 2 * MAX_VARINT_SIZE;

    // Note: There is a difference between this function and writeVarUInt() from IO/VarInt.h:
    // Google protobuf's representation of 64-bit integer contains from 1 to 10 bytes,
    // whileas writeVarUInt() writes from 1 to 9 bytes because it omits the tenth byte (which is not necessary to decode actually).
    void writeVarint(UInt64 value, WriteBuffer & out)
    {
        while (value >= 0x80)
        {
            out.write(static_cast<char>(value | 0x80));
            value >>= 7;
        }
        out.write(static_cast<char>(value));
    }

    UInt8 * writeVarint(UInt64 value, UInt8 * ptr)
    {
        while (value >= 0x80)
        {
            *ptr++ = static_cast<UInt8>(value | 0x80);
            value >>= 7;
        }
        *ptr++ = static_cast<UInt8>(value);
        return ptr;
    }

    void writeVarint(UInt64 value, PODArray<UInt8> & buf)
    {
        size_t old_size = buf.size();
        buf.reserve(old_size + MAX_VARINT_SIZE);
        UInt8 * ptr = buf.data() + old_size;
        ptr = writeVarint(value, ptr);
        buf.resize_assume_reserved(ptr - buf.data());
    }

    UInt64 encodeZigZag(Int64 value) { return (static_cast<UInt64>(value) << 1) ^ static_cast<UInt64>(value >> 63); }

    enum WireType
    {
        VARINT = 0,
        BITS64 = 1,
        LENGTH_DELIMITED = 2,
        GROUP_START = 3,
        GROUP_END = 4,
        BITS32 = 5
    };

    UInt8 * writeFieldNumber(UInt32 field_number, WireType wire_type, UInt8 * ptr)
    {
        return writeVarint((field_number << 3) | wire_type, ptr);
    }

    void writeFieldNumber(UInt32 field_number, WireType wire_type, PODArray<UInt8> & buf) { writeVarint((field_number << 3) | wire_type, buf); }

    // Should we pack repeated values while storing them.
    // It depends on type of the field in the protobuf schema and the syntax of that schema.
    bool shouldPackRepeated(const google::protobuf::FieldDescriptor * field)
    {
        if (!field->is_repeated())
            return false;
        switch (field->type())
        {
            case google::protobuf::FieldDescriptor::TYPE_INT32:
            case google::protobuf::FieldDescriptor::TYPE_UINT32:
            case google::protobuf::FieldDescriptor::TYPE_SINT32:
            case google::protobuf::FieldDescriptor::TYPE_INT64:
            case google::protobuf::FieldDescriptor::TYPE_UINT64:
            case google::protobuf::FieldDescriptor::TYPE_SINT64:
            case google::protobuf::FieldDescriptor::TYPE_FIXED32:
            case google::protobuf::FieldDescriptor::TYPE_SFIXED32:
            case google::protobuf::FieldDescriptor::TYPE_FIXED64:
            case google::protobuf::FieldDescriptor::TYPE_SFIXED64:
            case google::protobuf::FieldDescriptor::TYPE_FLOAT:
            case google::protobuf::FieldDescriptor::TYPE_DOUBLE:
            case google::protobuf::FieldDescriptor::TYPE_BOOL:
            case google::protobuf::FieldDescriptor::TYPE_ENUM:
                break;
            default:
                return false;
        }
        if (field->options().has_packed())
            return field->options().packed();
        return field->file()->syntax() == google::protobuf::FileDescriptor::SYNTAX_PROTO3;
    }

    // Should we omit null values (zero for numbers / empty string for strings) while storing them.
    bool shouldSkipNullValue(const google::protobuf::FieldDescriptor * field)
    {
        return field->is_optional() && (field->file()->syntax() == google::protobuf::FileDescriptor::SYNTAX_PROTO3);
    }
}

// SimpleWriter is an utility class to serialize protobufs.
// Knows nothing about protobuf schemas, just provides useful functions to serialize data.
ProtobufWriter::SimpleWriter::SimpleWriter(WriteBuffer & out_) : out(out_), current_piece_start(0), num_bytes_skipped(0)
{
}

ProtobufWriter::SimpleWriter::~SimpleWriter() = default;

void ProtobufWriter::SimpleWriter::startMessage()
{
}

void ProtobufWriter::SimpleWriter::endMessage()
{
    pieces.emplace_back(current_piece_start, buffer.size());
    size_t size_of_message = buffer.size() - num_bytes_skipped;
    writeVarint(size_of_message, out);
    for (const auto & piece : pieces)
        out.write(reinterpret_cast<char *>(&buffer[piece.start]), piece.end - piece.start);
    buffer.clear();
    pieces.clear();
    num_bytes_skipped = 0;
    current_piece_start = 0;
}

void ProtobufWriter::SimpleWriter::startNestedMessage()
{
    nested_infos.emplace_back(pieces.size(), num_bytes_skipped);
    pieces.emplace_back(current_piece_start, buffer.size());

    // We skip enough bytes to have place for inserting the field number and the size of the nested message afterwards
    // when we finish writing the nested message itself. We don't know the size of the nested message at the point of
    // calling startNestedMessage(), that's why we have to do this skipping.
    current_piece_start = buffer.size() + NESTED_MESSAGE_PADDING;
    buffer.resize(current_piece_start);
    num_bytes_skipped = NESTED_MESSAGE_PADDING;
}

void ProtobufWriter::SimpleWriter::endNestedMessage(UInt32 field_number, bool is_group, bool skip_if_empty)
{
    const auto & nested_info = nested_infos.back();
    size_t num_pieces_at_start = nested_info.num_pieces_at_start;
    size_t num_bytes_skipped_at_start = nested_info.num_bytes_skipped_at_start;
    nested_infos.pop_back();
    auto & piece_before_message = pieces[num_pieces_at_start];
    size_t message_start = piece_before_message.end;
    size_t message_size = buffer.size() - message_start - num_bytes_skipped;
    if (!message_size && skip_if_empty)
    {
        current_piece_start = piece_before_message.start;
        buffer.resize(piece_before_message.end);
        pieces.resize(num_pieces_at_start);
        num_bytes_skipped = num_bytes_skipped_at_start;
        return;
    }
    size_t num_bytes_inserted;
    if (is_group)
    {
        writeFieldNumber(field_number, GROUP_END, buffer);
        UInt8 * ptr = &buffer[piece_before_message.end];
        UInt8 * endptr = writeFieldNumber(field_number, GROUP_START, ptr);
        num_bytes_inserted = endptr - ptr;
    }
    else
    {
        UInt8 * ptr = &buffer[piece_before_message.end];
        UInt8 * endptr = writeFieldNumber(field_number, LENGTH_DELIMITED, ptr);
        endptr = writeVarint(message_size, endptr);
        num_bytes_inserted = endptr - ptr;
    }
    piece_before_message.end += num_bytes_inserted;
    num_bytes_skipped += num_bytes_skipped_at_start - num_bytes_inserted;
}

void ProtobufWriter::SimpleWriter::writeUInt(UInt32 field_number, UInt64 value)
{
    size_t old_size = buffer.size();
    buffer.reserve(old_size + 2 * MAX_VARINT_SIZE);
    UInt8 * ptr = buffer.data() + old_size;
    ptr = writeFieldNumber(field_number, VARINT, ptr);
    ptr = writeVarint(value, ptr);
    buffer.resize_assume_reserved(ptr - buffer.data());
}

void ProtobufWriter::SimpleWriter::writeInt(UInt32 field_number, Int64 value)
{
    writeUInt(field_number, static_cast<UInt64>(value));
}

void ProtobufWriter::SimpleWriter::writeSInt(UInt32 field_number, Int64 value)
{
    writeUInt(field_number, encodeZigZag(value));
}

template <typename T>
void ProtobufWriter::SimpleWriter::writeFixed(UInt32 field_number, T value)
{
    static_assert((sizeof(T) == 4) || (sizeof(T) == 8));
    constexpr WireType wire_type = (sizeof(T) == 4) ? BITS32 : BITS64;
    size_t old_size = buffer.size();
    buffer.reserve(old_size + MAX_VARINT_SIZE + sizeof(T));
    UInt8 * ptr = buffer.data() + old_size;
    ptr = writeFieldNumber(field_number, wire_type, ptr);
    memcpy(ptr, &value, sizeof(T));
    ptr += sizeof(T);
    buffer.resize_assume_reserved(ptr - buffer.data());
}

void ProtobufWriter::SimpleWriter::writeString(UInt32 field_number, const StringRef & str)
{
    size_t old_size = buffer.size();
    buffer.reserve(old_size + 2 * MAX_VARINT_SIZE + str.size);
    UInt8 * ptr = buffer.data() + old_size;
    ptr = writeFieldNumber(field_number, LENGTH_DELIMITED, ptr);
    ptr = writeVarint(str.size, ptr);
    memcpy(ptr, str.data, str.size);
    ptr += str.size;
    buffer.resize_assume_reserved(ptr - buffer.data());
}

void ProtobufWriter::SimpleWriter::startRepeatedPack()
{
    pieces.emplace_back(current_piece_start, buffer.size());

    // We skip enough bytes to have place for inserting the field number and the size of the repeated pack afterwards
    // when we finish writing the repeated pack itself. We don't know the size of the repeated pack at the point of
    // calling startRepeatedPack(), that's why we have to do this skipping.
    current_piece_start = buffer.size() + REPEATED_PACK_PADDING;
    buffer.resize(current_piece_start);
    num_bytes_skipped += REPEATED_PACK_PADDING;
}

void ProtobufWriter::SimpleWriter::endRepeatedPack(UInt32 field_number)
{
    size_t size = buffer.size() - current_piece_start;
    if (!size)
    {
        current_piece_start = pieces.back().start;
        buffer.resize(pieces.back().end);
        pieces.pop_back();
        num_bytes_skipped -= REPEATED_PACK_PADDING;
        return;
    }
    UInt8 * ptr = &buffer[pieces.back().end];
    UInt8 * endptr = writeFieldNumber(field_number, LENGTH_DELIMITED, ptr);
    endptr = writeVarint(size, endptr);
    size_t num_bytes_inserted = endptr - ptr;
    pieces.back().end += num_bytes_inserted;
    num_bytes_skipped -= num_bytes_inserted;
}

void ProtobufWriter::SimpleWriter::addUIntToRepeatedPack(UInt64 value)
{
    writeVarint(value, buffer);
}

void ProtobufWriter::SimpleWriter::addIntToRepeatedPack(Int64 value)
{
    writeVarint(static_cast<UInt64>(value), buffer);
}

void ProtobufWriter::SimpleWriter::addSIntToRepeatedPack(Int64 value)
{
    writeVarint(encodeZigZag(value), buffer);
}

template <typename T>
void ProtobufWriter::SimpleWriter::addFixedToRepeatedPack(T value)
{
    static_assert((sizeof(T) == 4) || (sizeof(T) == 8));
    size_t old_size = buffer.size();
    buffer.resize(old_size + sizeof(T));
    memcpy(buffer.data() + old_size, &value, sizeof(T));
}

// Implementation for a converter from any DB data type to any protobuf field type.
class ProtobufWriter::ConverterBaseImpl : public IConverter
{
public:
    ConverterBaseImpl(SimpleWriter & simple_writer_, const google::protobuf::FieldDescriptor * field_)
        : simple_writer(simple_writer_), field(field_)
    {
        field_number = field->number();
    }

    virtual void writeString(const StringRef &) override { cannotConvertType("String"); }
    virtual void writeInt8(Int8) override { cannotConvertType("Int8"); }
    virtual void writeUInt8(UInt8) override { cannotConvertType("UInt8"); }
    virtual void writeInt16(Int16) override { cannotConvertType("Int16"); }
    virtual void writeUInt16(UInt16) override { cannotConvertType("UInt16"); }
    virtual void writeInt32(Int32) override { cannotConvertType("Int32"); }
    virtual void writeUInt32(UInt32) override { cannotConvertType("UInt32"); }
    virtual void writeInt64(Int64) override { cannotConvertType("Int64"); }
    virtual void writeUInt64(UInt64) override { cannotConvertType("UInt64"); }
    virtual void writeUInt128(const UInt128 &) override { cannotConvertType("UInt128"); }
    virtual void writeFloat32(Float32) override { cannotConvertType("Float32"); }
    virtual void writeFloat64(Float64) override { cannotConvertType("Float64"); }
    virtual void prepareEnumMapping8(const std::vector<std::pair<std::string, Int8>> &) override {}
    virtual void prepareEnumMapping16(const std::vector<std::pair<std::string, Int16>> &) override {}
    virtual void writeEnum8(Int8) override { cannotConvertType("Enum"); }
    virtual void writeEnum16(Int16) override { cannotConvertType("Enum"); }
    virtual void writeUUID(const UUID &) override { cannotConvertType("UUID"); }
    virtual void writeDate(DayNum) override { cannotConvertType("Date"); }
    virtual void writeDateTime(time_t) override { cannotConvertType("DateTime"); }
    virtual void writeDecimal32(Decimal32, UInt32) override { cannotConvertType("Decimal32"); }
    virtual void writeDecimal64(Decimal64, UInt32) override { cannotConvertType("Decimal64"); }
    virtual void writeDecimal128(const Decimal128 &, UInt32) override { cannotConvertType("Decimal128"); }

    virtual void writeAggregateFunction(const AggregateFunctionPtr &, ConstAggregateDataPtr) override { cannotConvertType("AggregateFunction"); }

protected:
    [[noreturn]] void cannotConvertType(const String & type_name)
    {
        throw Exception(
            "Could not convert data type '" + type_name + "' to protobuf type '" + field->type_name() + "' (field: " + field->name() + ")",
            ErrorCodes::PROTOBUF_BAD_CAST);
    }

    [[noreturn]] void cannotConvertValue(const String & value)
    {
        throw Exception(
            "Could not convert value '" + value + "' to protobuf type '" + field->type_name() + "' (field: " + field->name() + ")",
            ErrorCodes::PROTOBUF_BAD_CAST);
    }

    template <typename To, typename From>
    To numericCast(From value)
    {
        if constexpr (std::is_same_v<To, From>)
            return value;
        To result;
        try
        {
            result = boost::numeric_cast<To>(value);
        }
        catch (boost::numeric::bad_numeric_cast &)
        {
            cannotConvertValue(toString(value));
        }
        return result;
    }

    template <typename To>
    To parseFromString(const StringRef & str)
    {
        To result;
        try
        {
            result = ::DB::parse<To>(str.data, str.size);
        }
        catch (...)
        {
            cannotConvertValue(str.toString());
        }
        return result;
    }

    SimpleWriter & simple_writer;
    const google::protobuf::FieldDescriptor * field;
    UInt32 field_number;
};

template <bool skip_null_value>
class ProtobufWriter::ConverterToString : public ConverterBaseImpl
{
public:
    using ConverterBaseImpl::ConverterBaseImpl;

    void writeString(const StringRef & str) override { writeField(str); }

    void writeInt8(Int8 value) override { convertToStringAndWriteField(value); }
    void writeUInt8(UInt8 value) override { convertToStringAndWriteField(value); }
    void writeInt16(Int16 value) override { convertToStringAndWriteField(value); }
    void writeUInt16(UInt16 value) override { convertToStringAndWriteField(value); }
    void writeInt32(Int32 value) override { convertToStringAndWriteField(value); }
    void writeUInt32(UInt32 value) override { convertToStringAndWriteField(value); }
    void writeInt64(Int64 value) override { convertToStringAndWriteField(value); }
    void writeUInt64(UInt64 value) override { convertToStringAndWriteField(value); }
    void writeFloat32(Float32 value) override { convertToStringAndWriteField(value); }
    void writeFloat64(Float64 value) override { convertToStringAndWriteField(value); }

    void prepareEnumMapping8(const std::vector<std::pair<String, Int8>> & name_value_pairs) override
    {
        prepareEnumValueToNameMap(name_value_pairs);
    }
    void prepareEnumMapping16(const std::vector<std::pair<String, Int16>> & name_value_pairs) override
    {
        prepareEnumValueToNameMap(name_value_pairs);
    }

    void writeEnum8(Int8 value) override { writeEnum16(value); }

    void writeEnum16(Int16 value) override
    {
        auto it = enum_value_to_name_map->find(value);
        if (it == enum_value_to_name_map->end())
            cannotConvertValue(toString(value));
        writeField(it->second);
    }

    void writeUUID(const UUID & uuid) override { convertToStringAndWriteField(uuid); }
    void writeDate(DayNum date) override { convertToStringAndWriteField(date); }

    void writeDateTime(time_t tm) override
    {
        writeDateTimeText(tm, text_buffer);
        writeField(text_buffer.stringRef());
        text_buffer.restart();
    }

    void writeDecimal32(Decimal32 decimal, UInt32 scale) override { writeDecimal(decimal, scale); }
    void writeDecimal64(Decimal64 decimal, UInt32 scale) override { writeDecimal(decimal, scale); }
    void writeDecimal128(const Decimal128 & decimal, UInt32 scale) override { writeDecimal(decimal, scale); }

    void writeAggregateFunction(const AggregateFunctionPtr & function, ConstAggregateDataPtr place) override
    {
        function->serialize(place, text_buffer);
        writeField(text_buffer.stringRef());
        text_buffer.restart();
    }

private:
    template <typename T>
    void convertToStringAndWriteField(T value)
    {
        writeText(value, text_buffer);
        writeField(text_buffer.stringRef());
        text_buffer.restart();
    }

    template <typename T>
    void writeDecimal(const Decimal<T> & decimal, UInt32 scale)
    {
        writeText(decimal, scale, text_buffer);
        writeField(text_buffer.stringRef());
        text_buffer.restart();
    }

    template <typename T>
    void prepareEnumValueToNameMap(const std::vector<std::pair<String, T>> & name_value_pairs)
    {
        if (enum_value_to_name_map.has_value())
            return;
        enum_value_to_name_map.emplace();
        for (const auto & name_value_pair : name_value_pairs)
            enum_value_to_name_map->emplace(name_value_pair.second, name_value_pair.first);
    }

    void writeField(const StringRef & str)
    {
        if constexpr (skip_null_value)
        {
            if (!str.size)
                return;
        }
        simple_writer.writeString(field_number, str);
    }

    WriteBufferFromOwnString text_buffer;
    std::optional<std::unordered_map<Int16, String>> enum_value_to_name_map;
};

#define PROTOBUF_WRITER_CREATE_CONVERTER_SPECIALIZATION_FOR_STRINGS(field_type_id) \
    template <> \
    std::unique_ptr<ProtobufWriter::IConverter> ProtobufWriter::createConverter<field_type_id>( \
        const google::protobuf::FieldDescriptor * field) \
    { \
        if (shouldSkipNullValue(field)) \
            return std::make_unique<ConverterToString<true>>(simple_writer, field); \
        else \
            return std::make_unique<ConverterToString<false>>(simple_writer, field); \
    }
PROTOBUF_WRITER_CREATE_CONVERTER_SPECIALIZATION_FOR_STRINGS(google::protobuf::FieldDescriptor::TYPE_STRING)
PROTOBUF_WRITER_CREATE_CONVERTER_SPECIALIZATION_FOR_STRINGS(google::protobuf::FieldDescriptor::TYPE_BYTES)
#undef PROTOBUF_WRITER_CREATE_CONVERTER_SPECIALIZATION_FOR_STRINGS

template <int field_type_id, typename ToType, bool skip_null_value, bool pack_repeated>
class ProtobufWriter::ConverterToNumber : public ConverterBaseImpl
{
public:
    using ConverterBaseImpl::ConverterBaseImpl;

    void writeString(const StringRef & str) override { writeField(parseFromString<ToType>(str)); }

    void writeInt8(Int8 value) override { castNumericAndWriteField(value); }
    void writeUInt8(UInt8 value) override { castNumericAndWriteField(value); }
    void writeInt16(Int16 value) override { castNumericAndWriteField(value); }
    void writeUInt16(UInt16 value) override { castNumericAndWriteField(value); }
    void writeInt32(Int32 value) override { castNumericAndWriteField(value); }
    void writeUInt32(UInt32 value) override { castNumericAndWriteField(value); }
    void writeInt64(Int64 value) override { castNumericAndWriteField(value); }
    void writeUInt64(UInt64 value) override { castNumericAndWriteField(value); }
    void writeFloat32(Float32 value) override { castNumericAndWriteField(value); }
    void writeFloat64(Float64 value) override { castNumericAndWriteField(value); }

    void writeEnum8(Int8 value) override { writeEnum16(value); }

    void writeEnum16(Int16 value) override
    {
        if constexpr (!std::is_integral_v<ToType>)
            cannotConvertType("Enum"); // It's not correct to convert enum to floating point.
        castNumericAndWriteField(value);
    }

    void writeDate(DayNum date) override { castNumericAndWriteField(static_cast<UInt16>(date)); }
    void writeDateTime(time_t tm) override { castNumericAndWriteField(tm); }

    void writeDecimal32(Decimal32 decimal, UInt32 scale) override { writeDecimal(decimal, scale); }
    void writeDecimal64(Decimal64 decimal, UInt32 scale) override { writeDecimal(decimal, scale); }
    void writeDecimal128(const Decimal128 & decimal, UInt32 scale) override { writeDecimal(decimal, scale); }

private:
    template <typename FromType>
    void castNumericAndWriteField(FromType value)
    {
        writeField(numericCast<ToType>(value));
    }

    template <typename S>
    void writeDecimal(const Decimal<S> & decimal, UInt32 scale)
    {
        castNumericAndWriteField(convertFromDecimal<DataTypeDecimal<Decimal<S>>, DataTypeNumber<ToType>>(decimal.value, scale));
    }

    void writeField(ToType value)
    {
        if constexpr (skip_null_value)
        {
            if (value == 0)
                return;
        }
        if constexpr (((field_type_id == google::protobuf::FieldDescriptor::TYPE_INT32) && std::is_same_v<ToType, Int32>)
                   || ((field_type_id == google::protobuf::FieldDescriptor::TYPE_INT64) && std::is_same_v<ToType, Int64>))
        {
            if constexpr (pack_repeated)
                simple_writer.addIntToRepeatedPack(value);
            else
                simple_writer.writeInt(field_number, value);
        }
        else if constexpr (((field_type_id == google::protobuf::FieldDescriptor::TYPE_SINT32) && std::is_same_v<ToType, Int32>)
                        || ((field_type_id == google::protobuf::FieldDescriptor::TYPE_SINT64) && std::is_same_v<ToType, Int64>))
        {
            if constexpr (pack_repeated)
                simple_writer.addSIntToRepeatedPack(value);
            else
                simple_writer.writeSInt(field_number, value);
        }
        else if constexpr (((field_type_id == google::protobuf::FieldDescriptor::TYPE_UINT32) && std::is_same_v<ToType, UInt32>)
                        || ((field_type_id == google::protobuf::FieldDescriptor::TYPE_UINT64) && std::is_same_v<ToType, UInt64>))
        {
            if constexpr (pack_repeated)
                simple_writer.addUIntToRepeatedPack(value);
            else
                simple_writer.writeUInt(field_number, value);
        }
        else
        {
            static_assert(((field_type_id == google::protobuf::FieldDescriptor::TYPE_FIXED32) && std::is_same_v<ToType, UInt32>)
                       || ((field_type_id == google::protobuf::FieldDescriptor::TYPE_SFIXED32) && std::is_same_v<ToType, Int32>)
                       || ((field_type_id == google::protobuf::FieldDescriptor::TYPE_FIXED64) && std::is_same_v<ToType, UInt64>)
                       || ((field_type_id == google::protobuf::FieldDescriptor::TYPE_SFIXED64) && std::is_same_v<ToType, Int64>)
                       || ((field_type_id == google::protobuf::FieldDescriptor::TYPE_FLOAT) && std::is_same_v<ToType, float>)
                       || ((field_type_id == google::protobuf::FieldDescriptor::TYPE_DOUBLE) && std::is_same_v<ToType, double>));
            if constexpr (pack_repeated)
                simple_writer.addFixedToRepeatedPack(value);
            else
                simple_writer.writeFixed(field_number, value);
        }
    }
};

#define PROTOBUF_WRITER_CREATE_CONVERTER_SPECIALIZATION_FOR_NUMBERS(field_type_id, field_type) \
    template <> \
    std::unique_ptr<ProtobufWriter::IConverter> ProtobufWriter::createConverter<field_type_id>( \
        const google::protobuf::FieldDescriptor * field) \
    { \
        if (shouldSkipNullValue(field)) \
            return std::make_unique<ConverterToNumber<field_type_id, field_type, true, false>>(simple_writer, field); \
        else if (shouldPackRepeated(field)) \
            return std::make_unique<ConverterToNumber<field_type_id, field_type, false, true>>(simple_writer, field); \
        else \
            return std::make_unique<ConverterToNumber<field_type_id, field_type, false, false>>(simple_writer, field); \
    }
PROTOBUF_WRITER_CREATE_CONVERTER_SPECIALIZATION_FOR_NUMBERS(google::protobuf::FieldDescriptor::TYPE_INT32, Int32);
PROTOBUF_WRITER_CREATE_CONVERTER_SPECIALIZATION_FOR_NUMBERS(google::protobuf::FieldDescriptor::TYPE_SINT32, Int32);
PROTOBUF_WRITER_CREATE_CONVERTER_SPECIALIZATION_FOR_NUMBERS(google::protobuf::FieldDescriptor::TYPE_UINT32, UInt32);
PROTOBUF_WRITER_CREATE_CONVERTER_SPECIALIZATION_FOR_NUMBERS(google::protobuf::FieldDescriptor::TYPE_INT64, Int64);
PROTOBUF_WRITER_CREATE_CONVERTER_SPECIALIZATION_FOR_NUMBERS(google::protobuf::FieldDescriptor::TYPE_SINT64, Int64);
PROTOBUF_WRITER_CREATE_CONVERTER_SPECIALIZATION_FOR_NUMBERS(google::protobuf::FieldDescriptor::TYPE_UINT64, UInt64);
PROTOBUF_WRITER_CREATE_CONVERTER_SPECIALIZATION_FOR_NUMBERS(google::protobuf::FieldDescriptor::TYPE_FIXED32, UInt32);
PROTOBUF_WRITER_CREATE_CONVERTER_SPECIALIZATION_FOR_NUMBERS(google::protobuf::FieldDescriptor::TYPE_SFIXED32, Int32);
PROTOBUF_WRITER_CREATE_CONVERTER_SPECIALIZATION_FOR_NUMBERS(google::protobuf::FieldDescriptor::TYPE_FIXED64, UInt64);
PROTOBUF_WRITER_CREATE_CONVERTER_SPECIALIZATION_FOR_NUMBERS(google::protobuf::FieldDescriptor::TYPE_SFIXED64, Int64);
PROTOBUF_WRITER_CREATE_CONVERTER_SPECIALIZATION_FOR_NUMBERS(google::protobuf::FieldDescriptor::TYPE_FLOAT, float);
PROTOBUF_WRITER_CREATE_CONVERTER_SPECIALIZATION_FOR_NUMBERS(google::protobuf::FieldDescriptor::TYPE_DOUBLE, double);
#undef PROTOBUF_WRITER_CREATE_CONVERTER_SPECIALIZATION_FOR_NUMBERS

template <bool skip_null_value, bool pack_repeated>
class ProtobufWriter::ConverterToBool : public ConverterBaseImpl
{
public:
    using ConverterBaseImpl::ConverterBaseImpl;

    void writeString(const StringRef & str) override
    {
        if (str == "true")
            writeField(true);
        else if (str == "false")
            writeField(false);
        else
            cannotConvertValue(str.toString());
    }

    void writeInt8(Int8 value) override { convertToBoolAndWriteField(value); }
    void writeUInt8(UInt8 value) override { convertToBoolAndWriteField(value); }
    void writeInt16(Int16 value) override { convertToBoolAndWriteField(value); }
    void writeUInt16(UInt16 value) override { convertToBoolAndWriteField(value); }
    void writeInt32(Int32 value) override { convertToBoolAndWriteField(value); }
    void writeUInt32(UInt32 value) override { convertToBoolAndWriteField(value); }
    void writeInt64(Int64 value) override { convertToBoolAndWriteField(value); }
    void writeUInt64(UInt64 value) override { convertToBoolAndWriteField(value); }
    void writeFloat32(Float32 value) override { convertToBoolAndWriteField(value); }
    void writeFloat64(Float64 value) override { convertToBoolAndWriteField(value); }
    void writeDecimal32(Decimal32 decimal, UInt32) override { convertToBoolAndWriteField(decimal.value); }
    void writeDecimal64(Decimal64 decimal, UInt32) override { convertToBoolAndWriteField(decimal.value); }
    void writeDecimal128(const Decimal128 & decimal, UInt32) override { convertToBoolAndWriteField(decimal.value); }

private:
    template <typename T>
    void convertToBoolAndWriteField(T value)
    {
        writeField(static_cast<bool>(value));
    }

    void writeField(bool b)
    {
        if constexpr (skip_null_value)
        {
            if (!b)
                return;
        }
        if constexpr (pack_repeated)
            simple_writer.addUIntToRepeatedPack(b);
        else
            simple_writer.writeUInt(field_number, b);
    }
};

template <>
std::unique_ptr<ProtobufWriter::IConverter> ProtobufWriter::createConverter<google::protobuf::FieldDescriptor::TYPE_BOOL>(
    const google::protobuf::FieldDescriptor * field)
{
    if (shouldSkipNullValue(field))
        return std::make_unique<ConverterToBool<true, false>>(simple_writer, field);
    else if (shouldPackRepeated(field))
        return std::make_unique<ConverterToBool<false, true>>(simple_writer, field);
    else
        return std::make_unique<ConverterToBool<false, false>>(simple_writer, field);
}

template <bool skip_null_value, bool pack_repeated>
class ProtobufWriter::ConverterToEnum : public ConverterBaseImpl
{
public:
    using ConverterBaseImpl::ConverterBaseImpl;

    void writeString(const StringRef & str) override
    {
        prepareEnumNameToPbNumberMap();
        auto it = enum_name_to_pbnumber_map->find(str);
        if (it == enum_name_to_pbnumber_map->end())
            cannotConvertValue(str.toString());
        writeField(it->second);
    }

    void writeInt8(Int8 value) override { convertToEnumAndWriteField(value); }
    void writeUInt8(UInt8 value) override { convertToEnumAndWriteField(value); }
    void writeInt16(Int16 value) override { convertToEnumAndWriteField(value); }
    void writeUInt16(UInt16 value) override { convertToEnumAndWriteField(value); }
    void writeInt32(Int32 value) override { convertToEnumAndWriteField(value); }
    void writeUInt32(UInt32 value) override { convertToEnumAndWriteField(value); }
    void writeInt64(Int64 value) override { convertToEnumAndWriteField(value); }
    void writeUInt64(UInt64 value) override { convertToEnumAndWriteField(value); }

    void prepareEnumMapping8(const std::vector<std::pair<String, Int8>> & name_value_pairs) override
    {
        prepareEnumValueToPbNumberMap(name_value_pairs);
    }
    void prepareEnumMapping16(const std::vector<std::pair<String, Int16>> & name_value_pairs) override
    {
        prepareEnumValueToPbNumberMap(name_value_pairs);
    }

    void writeEnum8(Int8 value) override { writeEnum16(value); }

    void writeEnum16(Int16 value) override
    {
        int pbnumber;
        if (enum_value_always_equals_pbnumber)
            pbnumber = value;
        else
        {
            auto it = enum_value_to_pbnumber_map->find(value);
            if (it == enum_value_to_pbnumber_map->end())
                cannotConvertValue(toString(value));
            pbnumber = it->second;
        }
        writeField(pbnumber);
    }

private:
    template <typename T>
    void convertToEnumAndWriteField(T value)
    {
        const auto * enum_descriptor = field->enum_type()->FindValueByNumber(numericCast<int>(value));
        if (!enum_descriptor)
            cannotConvertValue(toString(value));
        writeField(enum_descriptor->number());
    }

    void prepareEnumNameToPbNumberMap()
    {
        if (enum_name_to_pbnumber_map.has_value())
            return;
        enum_name_to_pbnumber_map.emplace();
        const auto * enum_type = field->enum_type();
        for (int i = 0; i != enum_type->value_count(); ++i)
        {
            const auto * enum_value = enum_type->value(i);
            enum_name_to_pbnumber_map->emplace(enum_value->name(), enum_value->number());
        }
    }

    template <typename T>
    void prepareEnumValueToPbNumberMap(const std::vector<std::pair<String, T>> & name_value_pairs)
    {
        if (enum_value_to_pbnumber_map.has_value())
            return;
        enum_value_to_pbnumber_map.emplace();
        enum_value_always_equals_pbnumber = true;
        for (const auto & name_value_pair : name_value_pairs)
        {
            Int16 value = name_value_pair.second;
            const auto * enum_descriptor = field->enum_type()->FindValueByName(name_value_pair.first);
            if (enum_descriptor)
            {
                enum_value_to_pbnumber_map->emplace(value, enum_descriptor->number());
                if (value != enum_descriptor->number())
                    enum_value_always_equals_pbnumber = false;
            }
            else
                enum_value_always_equals_pbnumber = false;
        }
    }

    void writeField(int enum_pbnumber)
    {
        if constexpr (skip_null_value)
        {
            if (!enum_pbnumber)
                return;
        }
        if constexpr (pack_repeated)
            simple_writer.addUIntToRepeatedPack(enum_pbnumber);
        else
            simple_writer.writeUInt(field_number, enum_pbnumber);
    }

    std::optional<std::unordered_map<StringRef, int>> enum_name_to_pbnumber_map;
    std::optional<std::unordered_map<Int16, int>> enum_value_to_pbnumber_map;
    bool enum_value_always_equals_pbnumber;
};

template <>
std::unique_ptr<ProtobufWriter::IConverter> ProtobufWriter::createConverter<google::protobuf::FieldDescriptor::TYPE_ENUM>(
    const google::protobuf::FieldDescriptor * field)
{
    if (shouldSkipNullValue(field))
        return std::make_unique<ConverterToEnum<true, false>>(simple_writer, field);
    else if (shouldPackRepeated(field))
        return std::make_unique<ConverterToEnum<false, true>>(simple_writer, field);
    else
        return std::make_unique<ConverterToEnum<false, false>>(simple_writer, field);
}

ProtobufWriter::ProtobufWriter(
    WriteBuffer & out, const google::protobuf::Descriptor * message_type, const std::vector<String> & column_names)
    : simple_writer(out)
{
    std::vector<const google::protobuf::FieldDescriptor *> field_descriptors_without_match;
    root_message = ProtobufColumnMatcher::matchColumns<ColumnMatcherTraits>(column_names, message_type, field_descriptors_without_match);
    for (const auto * field_descriptor_without_match : field_descriptors_without_match)
    {
        if (field_descriptor_without_match->is_required())
            throw Exception(
                "Output doesn't have a column named '" + field_descriptor_without_match->name()
                    + "' which is required to write the output in the protobuf format.",
                ErrorCodes::NO_DATA_FOR_REQUIRED_PROTOBUF_FIELD);
    }
    setTraitsDataAfterMatchingColumns(root_message.get());
}

ProtobufWriter::~ProtobufWriter() = default;

void ProtobufWriter::setTraitsDataAfterMatchingColumns(Message * message)
{
    Field * parent_field = message->parent ? &message->parent->fields[message->index_in_parent] : nullptr;
    message->data.parent_field_number = parent_field ? parent_field->field_number : 0;
    message->data.is_required = parent_field && parent_field->data.is_required;

    if (parent_field && parent_field->data.is_repeatable)
        message->data.repeatable_container_message = message;
    else if (message->parent)
        message->data.repeatable_container_message = message->parent->data.repeatable_container_message;
    else
        message->data.repeatable_container_message = nullptr;

    message->data.is_group = parent_field && (parent_field->field_descriptor->type() == google::protobuf::FieldDescriptor::TYPE_GROUP);

    for (auto & field : message->fields)
    {
        field.data.is_repeatable = field.field_descriptor->is_repeated();
        field.data.is_required = field.field_descriptor->is_required();
        field.data.repeatable_container_message = message->data.repeatable_container_message;
        field.data.should_pack_repeated = shouldPackRepeated(field.field_descriptor);

        if (field.nested_message)
        {
            setTraitsDataAfterMatchingColumns(field.nested_message.get());
            continue;
        }
        switch (field.field_descriptor->type())
        {
#define PROTOBUF_WRITER_CONVERTER_CREATING_CASE(field_type_id) \
            case field_type_id: \
                field.data.converter = createConverter<field_type_id>(field.field_descriptor); \
                break
            PROTOBUF_WRITER_CONVERTER_CREATING_CASE(google::protobuf::FieldDescriptor::TYPE_STRING);
            PROTOBUF_WRITER_CONVERTER_CREATING_CASE(google::protobuf::FieldDescriptor::TYPE_BYTES);
            PROTOBUF_WRITER_CONVERTER_CREATING_CASE(google::protobuf::FieldDescriptor::TYPE_INT32);
            PROTOBUF_WRITER_CONVERTER_CREATING_CASE(google::protobuf::FieldDescriptor::TYPE_SINT32);
            PROTOBUF_WRITER_CONVERTER_CREATING_CASE(google::protobuf::FieldDescriptor::TYPE_UINT32);
            PROTOBUF_WRITER_CONVERTER_CREATING_CASE(google::protobuf::FieldDescriptor::TYPE_FIXED32);
            PROTOBUF_WRITER_CONVERTER_CREATING_CASE(google::protobuf::FieldDescriptor::TYPE_SFIXED32);
            PROTOBUF_WRITER_CONVERTER_CREATING_CASE(google::protobuf::FieldDescriptor::TYPE_INT64);
            PROTOBUF_WRITER_CONVERTER_CREATING_CASE(google::protobuf::FieldDescriptor::TYPE_SINT64);
            PROTOBUF_WRITER_CONVERTER_CREATING_CASE(google::protobuf::FieldDescriptor::TYPE_UINT64);
            PROTOBUF_WRITER_CONVERTER_CREATING_CASE(google::protobuf::FieldDescriptor::TYPE_FIXED64);
            PROTOBUF_WRITER_CONVERTER_CREATING_CASE(google::protobuf::FieldDescriptor::TYPE_SFIXED64);
            PROTOBUF_WRITER_CONVERTER_CREATING_CASE(google::protobuf::FieldDescriptor::TYPE_FLOAT);
            PROTOBUF_WRITER_CONVERTER_CREATING_CASE(google::protobuf::FieldDescriptor::TYPE_DOUBLE);
            PROTOBUF_WRITER_CONVERTER_CREATING_CASE(google::protobuf::FieldDescriptor::TYPE_BOOL);
            PROTOBUF_WRITER_CONVERTER_CREATING_CASE(google::protobuf::FieldDescriptor::TYPE_ENUM);
#undef PROTOBUF_WRITER_CONVERTER_CREATING_CASE
            default:
                throw Exception(
                    String("Protobuf type '") + field.field_descriptor->type_name() + "' isn't supported", ErrorCodes::NOT_IMPLEMENTED);
        }
    }
}

void ProtobufWriter::startMessage()
{
    current_message = root_message.get();
    current_field_index = 0;
    simple_writer.startMessage();
}

void ProtobufWriter::endMessage()
{
    if (!current_message)
        return;
    endWritingField();
    while (current_message->parent)
    {
        simple_writer.endNestedMessage(
            current_message->data.parent_field_number, current_message->data.is_group, !current_message->data.is_required);
        current_message = current_message->parent;
    }
    simple_writer.endMessage();
    current_message = nullptr;
}

bool ProtobufWriter::writeField(size_t & column_index)
{
    endWritingField();
    while (true)
    {
        if (current_field_index < current_message->fields.size())
        {
            Field & field = current_message->fields[current_field_index];
            if (!field.nested_message)
            {
                current_field = &current_message->fields[current_field_index];
                current_converter = current_field->data.converter.get();
                column_index = current_field->column_index;
                if (current_field->data.should_pack_repeated)
                    simple_writer.startRepeatedPack();
                return true;
            }
            simple_writer.startNestedMessage();
            current_message = field.nested_message.get();
            current_message->data.need_repeat = false;
            current_field_index = 0;
            continue;
        }
        if (current_message->parent)
        {
            simple_writer.endNestedMessage(
                current_message->data.parent_field_number, current_message->data.is_group, !current_message->data.is_required);
            if (current_message->data.need_repeat)
            {
                simple_writer.startNestedMessage();
                current_message->data.need_repeat = false;
                current_field_index = 0;
                continue;
            }
            current_field_index = current_message->index_in_parent + 1;
            current_message = current_message->parent;
            continue;
        }
        return false;
    }
}

void ProtobufWriter::endWritingField()
{
    if (!current_field)
        return;
    if (current_field->data.should_pack_repeated)
        simple_writer.endRepeatedPack(current_field->field_number);
    else if ((num_values == 0) && current_field->data.is_required)
        throw Exception(
            "No data for the required field '" + current_field->field_descriptor->name() + "'",
            ErrorCodes::NO_DATA_FOR_REQUIRED_PROTOBUF_FIELD);

    current_field = nullptr;
    current_converter = nullptr;
    num_values = 0;
    ++current_field_index;
}

void ProtobufWriter::setNestedMessageNeedsRepeat()
{
    if (current_field->data.repeatable_container_message)
        current_field->data.repeatable_container_message->data.need_repeat = true;
    else
        throw Exception(
            "Cannot write more than single value to the non-repeated field '" + current_field->field_descriptor->name() + "'",
            ErrorCodes::PROTOBUF_FIELD_NOT_REPEATED);
}

}
#endif

max_stars_repo_name: anrodigina/ClickHouse

max_issues_repo_name: anrodigina/ClickHouse

max_forks_repo_name: anrodigina/ClickHouse


text:
#include <boost/math/special_functions/fpclassify.hpp>
#include <boost/math/special_functions/round.hpp>
#include <sm/assert_macros.hpp>
#include <sm/kinematics/rotations.hpp>

namespace sm {
namespace kinematics {

// Euler angle rotations.
Eigen::Matrix3d Rx(double radians) {
    Eigen::Matrix3d C;
    double c = cos(radians);
    double s = sin(radians);
    C(0, 0) = 1;
    C(0, 1) = 0.0;
    C(0, 2) = 0;
    C(1, 0) = 0.0;
    C(1, 1) = c;
    C(1, 2) = -s;
    C(2, 0) = 0.0;
    C(2, 1) = s;
    C(2, 2) = c;

    return C;
}

Eigen::Matrix3d Ry(double radians) {
    Eigen::Matrix3d C;
    double c = cos(radians);
    double s = sin(radians);
    C(0, 0) = c;
    C(0, 1) = 0.0;
    C(0, 2) = s;
    C(1, 0) = 0.0;
    C(1, 1) = 1;
    C(1, 2) = 0.0;
    C(2, 0) = -s;
    C(2, 1) = 0.0;
    C(2, 2) = c;

    return C;
}
Eigen::Matrix3d Rz(double radians) {
    Eigen::Matrix3d C;
    double c = cos(radians);
    double s = sin(radians);
    C(0, 0) = c;
    C(0, 1) = -s;
    C(0, 2) = 0.0;
    C(1, 0) = s;
    C(1, 1) = c;
    C(1, 2) = 0.0;
    C(2, 0) = 0.0;
    C(2, 1) = 0.0;
    C(2, 2) = 1;

    return C;
}

Eigen::Matrix3d rph2R(double x, double y, double z) {
    Eigen::Matrix3d C;
    double cx = cos(x);
    double sx = sin(x);
    double cy = cos(y);
    double sy = sin(y);
    double cz = cos(z);
    double sz = sin(z);
    //[cos(z)*cos(y), -sin(z)*cos(x)+cos(z)*sin(y)*sin(x),  sin(z)*sin(x)+cos(z)*sin(y)*cos(x)]
    //[sin(z)*cos(y),  cos(z)*cos(x)+sin(z)*sin(y)*sin(x), -cos(z)*sin(x)+sin(z)*sin(y)*cos(x)]
    //[      -sin(y),                       cos(y)*sin(x),                       cos(y)*cos(x)]
    C(0, 0) = cz * cy;
    C(0, 1) = -sz * cx + cz * sy * sx;
    C(0, 2) = sz * sx + cz * sy * cx;
    C(1, 0) = sz * cy;
    C(1, 1) = cz * cx + sz * sy * sx;
    C(1, 2) = -cz * sx + sz * sy * cx;
    C(2, 0) = -sy;
    C(2, 1) = cy * sx;
    C(2, 2) = cy * cx;

    return C;
}
Eigen::Matrix3d rph2R(Eigen::Vector3d const& x) { return rph2R(x[0], x[1], x[2]); }

Eigen::Vector3d R2rph(Eigen::Matrix3d const& C) {
    double phi = asin(C(2, 0));
    double theta = atan2(C(2, 1), C(2, 2));
    double psi = atan2(C(1, 0), C(0, 0));

    Eigen::Vector3d ret;
    ret[0] = theta;
    ret[1] = -phi;
    ret[2] = psi;

    return ret;
}

//// Small angle approximation.
template <typename Scalar_>
Eigen::Matrix<Scalar_, 3, 3> crossMx(Scalar_ x, Scalar_ y, Scalar_ z) {
    Eigen::Matrix<Scalar_, 3, 3> C;
    C(0, 0) = 0.0;
    C(0, 1) = -z;
    C(0, 2) = y;
    C(1, 0) = z;
    C(1, 1) = 0.0;
    C(1, 2) = -x;
    C(2, 0) = -y;
    C(2, 1) = x;
    C(2, 2) = 0.0;
    return C;
}
template Eigen::Matrix<double, 3, 3> crossMx(double x, double y, double z);
template Eigen::Matrix<float, 3, 3> crossMx(float x, float y, float z);

template Eigen::Matrix<double, 3, 3> crossMx(Eigen::MatrixBase<Eigen::Matrix<double, 3, 1> > const&);
template Eigen::Matrix<float, 3, 3> crossMx(Eigen::MatrixBase<Eigen::Matrix<float, 3, 1> > const&);

template Eigen::Matrix<double, 3, 3> crossMx(Eigen::MatrixBase<Eigen::Matrix<double, Eigen::Dynamic, 1> > const&);
template Eigen::Matrix<float, 3, 3> crossMx(Eigen::MatrixBase<Eigen::Matrix<float, Eigen::Dynamic, 1> > const&);

// Axis Angle rotation.
Eigen::Matrix3d axisAngle2R(double a, double ax, double ay, double az) {
    SM_ASSERT_LT_DBG(std::runtime_error, fabs(sqrt(ax * ax + ay * ay + az * az) - 1.0), 1e-4,
                     "The axis is not a unit vector. ||a|| = " << (sqrt(ax * ax + ay * ay + az * az)));

    if (a < 1e-12) return Eigen::Matrix3d::Identity();
    // e = [ax ay az]
    // e*(e') + (eye(3) - e*(e'))*cos(a) - crossMx(e) * sin(a) =
    //[         ax^2+ca*(1-ax^2), ax*ay-ca*ax*ay+sa*az, ax*az-ca*ax*az-sa*ay]
    //[ ax*ay-ca*ax*ay-sa*az,         ay^2+ca*(1-ay^2), ay*az-ca*ay*az+sa*ax]
    //[ ax*az-ca*ax*az+sa*ay, ay*az-ca*ay*az-sa*ax,         az^2+ca*(1-az^2)]
    double sa = sin(a);
    double ca = cos(a);
    double ax2 = ax * ax;
    double ay2 = ay * ay;
    double az2 = az * az;
    double const one = double(1);

    Eigen::Matrix3d C;
    C(0, 0) = ax2 + ca * (one - ax2);
    C(0, 1) = ax * ay - ca * ax * ay + sa * az;
    C(0, 2) = ax * az - ca * ax * az - sa * ay;
    C(1, 0) = ax * ay - ca * ax * ay - sa * az;
    C(1, 1) = ay2 + ca * (one - ay2);
    C(1, 2) = ay * az - ca * ay * az + sa * ax;
    C(2, 0) = ax * az - ca * ax * az + sa * ay;
    C(2, 1) = ay * az - ca * ay * az - sa * ax;
    C(2, 2) = az2 + ca * (one - az2);

    return C;
}
Eigen::Matrix3d axisAngle2R(double x, double y, double z) {
    double a = sqrt(x * x + y * y + z * z);
    if (a < 1e-12) return Eigen::Matrix3d::Identity();

    double d = 1 / a;
    return axisAngle2R(a, x * d, y * d, z * d);
}

Eigen::Matrix3d axisAngle2R(Eigen::Vector3d const& x) { return axisAngle2R(x[0], x[1], x[2]); }

Eigen::Vector3d R2AxisAngle(Eigen::Matrix3d const& C) {
    // Sometimes, because of roundoff error, the value of tr ends up outside
    // the valid range of arccos. Truncate to the valid range.
    double tr = std::max(-1.0, std::min((C(0, 0) + C(1, 1) + C(2, 2) - 1.0) * 0.5, 1.0));
    double a = acos(tr);

    Eigen::Vector3d axis;

    if (fabs(a) < 1e-10) {
        return Eigen::Vector3d::Zero();
    }

    axis[0] = (C(2, 1) - C(1, 2));
    axis[1] = (C(0, 2) - C(2, 0));
    axis[2] = (C(1, 0) - C(0, 1));
    double n2 = axis.norm();
    if (fabs(n2) < 1e-10) return Eigen::Vector3d::Zero();

    double scale = -a / n2;
    axis = scale * axis;

    return axis;
}

// Utility functions
double angleMod(double radians) { return (double)(radians - (SM_2PI * boost::math::round(radians / SM_2PI))); }
double deg2rad(double degrees) { return (double)(degrees * SM_DEG2RAD); }
double rad2deg(double radians) { return (double)(radians * SM_RAD2DEG); }

Eigen::Matrix3d Cx(double radians) { return Rx(-radians); }
Eigen::Matrix3d Cy(double radians) { return Ry(-radians); }
Eigen::Matrix3d Cz(double radians) { return Rz(-radians); }

Eigen::Matrix3d rph2C(double x, double y, double z) { return rph2R(-x, -y, -z); }

Eigen::Matrix3d rph2C(Eigen::Vector3d const& x) { return rph2C(x[0], x[1], x[2]); }
Eigen::Matrix3d rph2C(Eigen::VectorXd const& x) {
    SM_ASSERT_EQ_DBG(std::runtime_error, x.size(), 3, "The input vector must have 3 components");
    return rph2C(x[0], x[1], x[2]);
}

Eigen::Matrix3d rph2C(Eigen::MatrixXd const& A, unsigned column) {
    SM_ASSERT_EQ_DBG(std::runtime_error, A.rows(), 3, "The input matrix must have 3 rows");
    SM_ASSERT_LT_DBG(std::runtime_error, column, A.cols(), "The requested column is out of bounds");
    return rph2C(A(0, column), A(1, column), A(2, column));
}

Eigen::Vector3d C2rph(Eigen::MatrixXd const& C) {
    SM_ASSERT_EQ_DBG(std::runtime_error, C.rows(), 3, "The input matrix must be 3x3");
    SM_ASSERT_EQ_DBG(std::runtime_error, C.cols(), 3, "The input matrix must be 3x3");

    Eigen::Vector3d rph;

    rph[1] = asin(C(2, 0));
    rph[2] = atan2(-C(1, 0), C(0, 0));
    rph[0] = atan2(-C(2, 1), C(2, 2));

    return rph;
}

Eigen::Vector3d C2rph(Eigen::Matrix3d const& C) {
    Eigen::Vector3d rph;

    rph[1] = asin(C(2, 0));
    rph[2] = atan2(-C(1, 0), C(0, 0));
    rph[0] = atan2(-C(2, 1), C(2, 2));

    return rph;
}

}  // namespace kinematics
}  // namespace sm

max_stars_repo_name: chengfzy/kalibr

max_issues_repo_name: chengfzy/kalibr

max_forks_repo_name: chengfzy/kalibr


text:
//======================================================================
/*! \file TripDbReader.cpp
 *
 * \copydoc Copyright
 * \author Kristian Bischoff (kb)
 * \date Feb 18, 2016
 *///-------------------------------------------------------------------
//======================================================================

#include <ibeosdk/devices/database/TripDbReader.hpp>
#include <ibeosdk/database/DbConnectionFactory.hpp>

#include <boost/algorithm/string/predicate.hpp>

//======================================================================

namespace ibeosdk {

//======================================================================

using namespace dbaccess;

//======================================================================

TripDbReader::TripDbReader()
    : m_dbInterface(),
      m_procInterface(),
      m_procItr()
{}

//======================================================================

void TripDbReader::connect()
{
	DbConnectionFactory::ScopedConnection sc;
	m_dbInterface = sc.getDbIfPtr();
}

//======================================================================

bool TripDbReader::getTrip(Trip& trip)
{
	CollectionName cInfoValues = CollectionName(trip.getFullDbName() + BaseEntity::ContentSuffix_InfoValues);
	CollectionName cProcessingJobs = CollectionName(trip.getFullDbName() + BaseEntity::ContentSuffix_ProcessingJobs);

	if(MongoDbUtils::collectionExists(m_dbInterface->m_mDbConnection->getDbClientConnection(), cInfoValues)) {
		mongo::BSONObj obj = m_dbInterface->queryOne(cInfoValues);

		if (obj.isEmpty()) {
			return false;
		}
		BsonT<Trip>::createTripInfo(trip, obj);
	}
	else {
		return false;
	}

	bool collectionCheck = false;
	DbConnectionFactory::ScopedConnection sc;
	m_procInterface = sc.getDbIfPtr<ProcessingJob>(cProcessingJobs, collectionCheck);

	if(collectionCheck) {
		m_procItr = m_procInterface->queryData();

		while (!m_procItr.end()) {
			trip.addProcessingJob(*m_procItr);
			++m_procItr;
		}
	}

	return true;
}

//======================================================================

TripList TripDbReader::getTrips()
{
	TripList tripList;

	std::list<std::string> dbNames = m_dbInterface->getDatabaseNames();

	std::list<std::string>::const_iterator it = dbNames.begin();
	for (; it != dbNames.end(); ++it) {
		if (boost::algorithm::starts_with(*it, BaseEntity::Content_Trip)) {
			Trip newTrip(it->substr(BaseEntity::Content_Trip.length()));

			if (getTrip(newTrip))
				tripList.push_back(newTrip);
		}
	} // for

	return tripList;
}

//======================================================================

void TripDbReader::fillTrips(dbaccess::TripList& list)
{
	TripList::iterator itr = list.begin();
	for (; itr != list.end(); ++itr)
		getTrip(*itr);
}

//======================================================================

} // namespace ibeosdk

//======================================================================


text:
#ifndef CPU_ONLY
#ifdef USE_PROF

#ifndef CAFFE_ASYNC_TRACKER_HPP_
#define CAFFE_ASYNC_TRACKER_HPP_

#include <iostream>
#include <fstream>
#include <sstream>
#include <algorithm>
#include <string>
#include <cstring>
#include <vector>
#include <map>

#include <cuda.h>
#include <cuda_runtime.h>
#include <cupti.h>

#include <glog/logging.h>

#include <boost/thread/mutex.hpp>

#include "caffe/util/res_struct.hpp"

/**
 * @brief Macro used to check CUDA runtime errors, and print the corresponding error
 * string.
 */
#define CHECK_CUDA_ERROR(err, functionName) {                   \
  if (err != cudaSuccess) {                                     \
    LOG(FATAL) << __FILE__ << "@" << __LINE__ << ": error " <<   \
      err << " for CUDA Runtime API function '" << functionName \
      << "': " << cudaGetErrorString(err) << std::endl;         \
    exit (EXIT_FAILURE);                                        \
  }                                                             \
}

/**
 * @brief Macro used to check CUPTI runtime errors, and print the corresponding error
 * string.
 */
#define CHECK_CUPTI_ERROR(err, cuptifunc)     {                         \
  if (err != CUPTI_SUCCESS) {                                           \
    const char* errstr;                                                 \
    cuptiGetResultString(err, &errstr);                                 \
    LOG(FATAL) << __FILE__ << "@" << __LINE__ << ": Error " << errstr << \
      " for CUPTI API function '" << cuptifunc << "'." << std::endl;    \
    exit(EXIT_FAILURE);                                                 \
  }                                                                     \
}

/**
 * @brief Macro used to check CUDA driver errors, and print the corresponding error
 * string.
 */
#define CHECK_CU_ERROR(err, functionName) {                     \
  if (err != CUDA_SUCCESS) {                                    \
    const char* errstr;                                         \
    cuGetErrorString(err, &errstr);                             \
    LOG(FATAL) << __FILE__ << "@" << __LINE__ << ": error " <<  \
      err << " for CUDA Driver API function '" << functionName  \
      << "': " << errstr << std::endl;                          \
    exit (EXIT_FAILURE);                                        \
  }                                                             \
}

/**
 * @brief Disable the copy and assignment operation of a class operation.
 */
#define DISABLE_COPY_AND_ASSIGN(classname)                      \
private:                                                        \
  classname(const classname&);                                  \
  classname& operator=(const classname&)                        \

/**
 * @brief Macro used to represent the buffer size allocated for kernel recording.
 */
#define BUFFER_SIZE (32 * 1024)
#define ALIGN_SIZE 8      // \brief Alignment size.
/**
 * @brief Macro used to align profiling buffer.
 */
#define ALIGN_BUFFER(buffer, align_size)                        \
  ((reinterpret_cast<uintptr_t>(buffer) & (align_size - 1)) ? (buffer + align_size - (reinterpret_cast<uintptr_t>(buffer) & (align_size - 1))) : buffer)

// Standard built-in class used in AsyncResTracker.
using std::string;
using std::vector;
using std::map;
using std::fstream;
using std::stringstream;

namespace caffe {
  enum PROFTYPE {DEFAULT = 0, SERIAL = 1, CONCURRENT = 2};

  /**
   * @brief AsyncResTracker class.
   *
   * @details Class used to track kernels in a network layer.
   */
  class AsyncResTracker {
    public:
      /**
       * @brief   AsyncResTracker deconstructor.
       */
      ~AsyncResTracker();

      /**
       * @brief   Object access method.
       *
       * Singleton asynchronous resource tracker object.
       */
      static AsyncResTracker& Get();

      /**
       * @brief   Initialize CUPTI settings of a class object.
       */
      static void InitAsyncResTracker(PROFTYPE prof_type = DEFAULT);

      /**
       * @brief   ProfilerLock function.
       *
       * Function used to lock a profiler.
       */
      void ProfilerLock() {
        this->profiler_mutex_.lock();
      }
      /**
       * @brief   ProfilerUnlock function.
       *
       * Function used to unlock a profiler.
       */
      void ProfilerUnlock() {
        this->profiler_mutex_.unlock();
      }

      /**
       * @brief   Kernel profiler starter.
       * @param[in] device_id    ID of the device needed to be profiled.
       *                         If device_id is lower than 0, then the
       *                         current device is profiled, otherwise
       *                         device device_id is profiled.
       */
      void ProfilerStart(int device_id = -1);
      /**
       * @brief   Kernel profiler stopper.
       */
      void ProfilerStop();

      /**
       * @brief   Buffer request function.
       *
       * Function used to handle buffer requests from CUPTI runtime. This function will allocate
       * buffers for CUPTI to store kernel records.
       *
       * @param[out] buffer     Buffer allocated for kernel profiling.
       * @param[out] size       Size of the buffer allocated.
       * @param[out] maxNumRecords The maximum number of records that should be placed in the buffer.
       *                           0 represents that the buffer is filled with as many records as
       *                           possible.
       */
      static void CUPTIAPI BufferRequested(uint8_t **buffer, size_t *size, size_t *maxNumRecords);
      /**
       * @brief   Buffer completion function.
       *
       * Function used by CUPTI to return a buffer of activity records. The buffer contains validSize
       * bytes of activity records which should be read using cuptiActivityGetNextRecord.
       *
       * @param[in] context     The context this buffer is associated with. This field is deprecated
       *                        as of CUDA 6.0 and will always be NULL.
       * @param[in] stream_id   CUDA stream ID.
       * @param[in] buffer      The activity record buffer.
       * @param[in] size
       * @param[in] validSize   Size of activity records in bytes.
       */
      static void CUPTIAPI BufferCompleted(CUcontext context, uint32_t stream_id, uint8_t *buffer, size_t size, size_t validSize);
      /**
       * @brief   Kernel record parse function.
       *
       * Parse the activity record and store the corresponding kernel name and kernel runtime
       * configuration.
       *
       * @param[in] record      A activity record from cuptiGetActivityGetNextRecord.
       */
      static void ParseKernelConfig(CUpti_Activity *record);
      /**
       * @brief   Kernel searching function.
       *
       * This function is used to check whether there is an identical kernel has been recorded.
       *
       * @param[in] kernel_vec_ptr  Kernel vector that stores kernels with the same key value.
       * @param[in] kernel          New kernel waiting for being processed.
       * @return  Index of the kernel in kernel_vec_ptr. It returns -1 if the kernel is not found.
       */
      static int FindKernelConfig(const vector<Kernel_t> *kernel_vec_ptr, Kernel_t& kernel);

      /**
       * @brief   GPU device setting function.
       * @param[in] device_id       New device needed to be profiled.
       */
      /*
      static void SetDevice(int device_id) {
        profiling_device_id_ = device_id;
      }
      */

      /**
       * @brief   Get the vector of kernels recorded.
       * @return  Reference to the vector of kernels.
       */
      vector<Kernel_t>& GetKernelsRecorded();
      /**
       * @brief   Get the overhead of launching a kernel.
       * @return  The overhead of launching a kernel on the current device.
       */
      uint64_t GetKernelLaunchOverhead();

      /**
       * @brief   Build a segment tree.
       * @param[in] seg_tree    Pointer to the root of the segment tree.
       * @param[in] node_id     ID of the available tree node.
       * @param[in] start       The start number of the segment tree.
       * @param[in] end         The end number of the segment tree.
       */
      void TreeBuild(SegTree_ptr seg_tree, int node_id, int start, int end);
      /**
       * @brief   Insert a tree node.
       * @param[in] seg_tree      Pointer to the root of the segment tree.
       * @param[in] current_node  ID of the available tree node.
       * @param[in] start         The start number of the segment tree.
       * @param[in] end           The end number of the segment tree.
       */
      void TreeInsert(SegTree_ptr seg_tree, int current_node, int start, int end);
      /**
       * @brief   Traverse the segment tree.
       * @param[in] seg_tree      Pointer to the root of the segment tree.
       * @param[in] time_vec      Timestamps of kernels recorded.
       * @param[in] node_id       The current tree node being visited.
       * @return  The total busy time of the GPU device.
       */
      uint64_t TreeTraverse(const SegTree_ptr seg_tree, const vector<uint64_t>& time_vec, int node_id);
      /**
       * @brief   Compute the device occupancy ratio.
       * @param[in] layer_name      Name of the current layer.
       * @param[in] parallel_degree The current parallel_degree configuration.
       */
      void ComputeOccupancyRatio(const string layer_name, const unsigned int parallel_degree);
      /**
       * @brief   Record the kernel timestamp.
       *
       * This method is used to write kernel timestamps recorded for further analysis.
       *
       * @param[in] filename        Name of the log file.
       * @param[in] timestamp_ptr   Kernel timestamp vector.
       */
      void TimestampLog(const string filename) const;
      /**
       * @brief   Temp buffer release method.
       *
       * Method used to release temporary buffer allocated while analyzing kernels recorded.
       */
      void TempBufRelease();

    protected:
      // Boost mutex used to lock the profiler.
      static boost::mutex profiler_mutex_;
      // Static member variable used to count the number of recorded kernels.
      static int static_kernel_counter_;
      // Member variable used to store the number of recorded kernels.
      unsigned int kernel_counter_;

      // Static member variable used to identify the profiling device.
      static int profiling_device_id_;
      // Member variable used to identify whether start profiling.
      static bool profiler_flag_;
      // Record kind of the current activity profiled.
      // static CUpti_ActivityKind cupti_act_kind_;

      // Static start timestamp of the profiling process.
      static uint64_t static_startTimestamp_;
      // Overhead used to launch a kernel.
      uint64_t kernel_launch_overhead_;

      // Static member variable used to point to kernel records.
      static vector<Kernel_t> *kernels_vec_ptr_;
      // Member variable used to maintain the recorded kernels.
      vector<Kernel_t> kernels_vec_;
      // Static member variable used to point to the vector storing kernel
      // timestamps.
      static vector<Timestamp_t> *timestamp_vec_ptr_;
      // Member variable used to store kernel timestamps.
      vector<Timestamp_t> timestamp_vec_;

      // The current profiling type: DEFAULT, SERIAL and CONCURRENT (valid values).
      static PROFTYPE curr_prof_type_;

      // Member variable used to represent the next available tree node ID.
      // Only used to construct the segment tree.
      unsigned int next_node_idx_;
      // Member variable used to represent the total number of nodes in segment
      // tree seg_tree_.
      unsigned int tree_nodes_count_;
      // Member variable used to point to the root node of segment tree seg_tree_.
      SegTree_ptr seg_tree_;

    private:
      // The private constructor to avoid duplicate instantiation.
      AsyncResTracker();

      DISABLE_COPY_AND_ASSIGN(AsyncResTracker);
  };
}   /** namespace caffe **/

#endif    /** CAFFE_ASYNC_TRACKER_HPP_ **/
#endif    /** USE_PROF **/
#endif    /** CPU_ONLY settings **/


text:
/*
Copyright (c) 2019 Matthew H. Reilly (kb1vc)
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.

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
HOLDER 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.
*/
#ifndef SAVE_REST_HDR_DEF
#define SAVE_REST_HDR_DEF
#include <vector>
#include <iostream>
#include <boost/format.hpp>

/**
 * \class GeoProf::SaveRestoreObj
 *
 * \brief Base class for all objects that can save themselves to a binary stream
 *
 * \author $Author: kb1vc $
 *
 * \date $Date: 2005/04/14 14:16:20 $
 *
 * Contact: kb1vc@kb1vc.org
 *
 */
namespace GeoProf {
  class SaveRestoreObj {
  public:
    SaveRestoreObj() {
    }

    virtual void save(std::ostream & os) = 0;

    virtual void restore(std::istream & os) = 0;
  };

}
#endif

ext: hxx