text:
//----------------------------------------------------------------------------
/// @file merge_block.hpp
/// @brief This file constains the class merge_block, which is part of the
///        block_indirect_sort algorithm
///
/// @author Copyright (c) 2016 Francisco Jose Tapia (fjtapia@gmail.com )\n
///         Distributed under the Boost Software License, Version 1.0.\n
///         ( See accompanying file LICENSE_1_0.txt or copy at
///           http://www.boost.org/LICENSE_1_0.txt  )
/// @version 0.1
///
/// @remarks
//-----------------------------------------------------------------------------
#ifndef __BOOST_SORT_COMMON_MERGE_BLOCK_HPP
#define __BOOST_SORT_COMMON_MERGE_BLOCK_HPP

#include <boost/sort/common/range.hpp>
#include <boost/sort/common/rearrange.hpp>
#include <boost/sort/common/util/merge.hpp>
#include <boost/sort/common/util/traits.hpp>

namespace boost
{
namespace sort
{
namespace common
{
///---------------------------------------------------------------------------
/// @struct merge_block
/// @brief This contains all the information shared betwen the classes of the
///        block indirect sort algorithm

//----------------------------------------------------------------------------
template<class Iter_t, class Compare, uint32_t Power2 = 10>
struct merge_block
{
    //-------------------------------------------------------------------------
    //                  D E F I N I T I O N S
    //-------------------------------------------------------------------------
    typedef util::value_iter<Iter_t>                    value_t;
    typedef range<size_t>                               range_pos;
    typedef range<Iter_t>                               range_it;
    typedef range<value_t *>                            range_buf;
    typedef typename std::vector<size_t>::iterator      it_index;
    typedef util::circular_buffer<value_t, Power2 + 1>  circular_t;

    //------------------------------------------------------------------------
    //                          CONSTANTS
    //------------------------------------------------------------------------
    const size_t BLOCK_SIZE = (size_t) 1 << Power2;
    const size_t LOG_BLOCK = Power2;

    //------------------------------------------------------------------------
    //                V A R I A B L E S
    //------------------------------------------------------------------------
    // range with all the element to sort
    range<Iter_t> global_range;

    // index vector of block_pos elements
    std::vector<size_t> index;

    // Number of elements to sort
    size_t nelem;

    // Number of blocks to sort
    size_t nblock;

    // Number of elements in the last block (tail)
    size_t ntail;

    // object for to compare two elements
    Compare cmp;

    // range  of elements of the last block (tail)
    range_it range_tail;

    // circular buffer
    circular_t * ptr_circ;

    // indicate  if the circulr buffer is owned  by the data structure
    // or is received as parameter
    bool owned;

    //
    //------------------------------------------------------------------------
    //                F U N C T I O N S
    //------------------------------------------------------------------------
    //
    //------------------------------------------------------------------------
    //  function : merge_block
    /// @brief constructor of the class
    //
    /// @param first : iterator to the first element of the range to sort
    /// @param last : iterator after the last element to the range to sort
    /// @param comp : object for to compare two elements pointed by Iter_t
    ///               iterators
    //------------------------------------------------------------------------
    merge_block (Iter_t first, Iter_t last, Compare comp,
                 circular_t *pcirc_buffer)
    : global_range(first, last), cmp(comp), ptr_circ(pcirc_buffer),
      owned(pcirc_buffer == nullptr)
    {
        assert((last - first) >= 0);
        if (first == last) return; // nothing to do

        nelem = size_t(last - first);
        nblock = (nelem + BLOCK_SIZE - 1) / BLOCK_SIZE;
        ntail = (nelem % BLOCK_SIZE);
        index.reserve(nblock + 1);

        for (size_t i = 0; i < nblock; ++i)
            index.emplace_back(i);

        range_tail.first = first + ((nblock - 1) << LOG_BLOCK);
        range_tail.last = last;
        if (owned)
        {
            ptr_circ = new circular_t;
            ptr_circ->initialize(*first);
        };
    }

    merge_block(Iter_t first, Iter_t last, Compare comp)
                    : merge_block(first, last, comp, nullptr) { };

    ~ merge_block()
    {
        if (ptr_circ != nullptr and owned)
        {
            delete ptr_circ;
            ptr_circ = nullptr;
        };
    };
    //-------------------------------------------------------------------------
    //  function : get_range
    /// @brief obtain the range in the position pos
    /// @param pos : position of the range
    /// @return range required
    //-------------------------------------------------------------------------
    range_it get_range(size_t pos) const
    {
        Iter_t it1 = global_range.first + (pos << LOG_BLOCK);
        Iter_t it2 = (pos == (nblock - 1)) ?
                        global_range.last : it1 + BLOCK_SIZE;
        return range_it(it1, it2);
    };
    //-------------------------------------------------------------------------
    //  function : get_group_range
    /// @brief obtain the range of the contiguous blocks beginning in the
    //         position pos
    /// @param pos : position of the first range
    /// @param nrange : number of ranges of the group
    /// @return range required
    //-------------------------------------------------------------------------
    range_it get_group_range(size_t pos, size_t nrange) const
    {
        Iter_t it1 = global_range.first + (pos << LOG_BLOCK);

        Iter_t it2 = ((pos + nrange) == nblock)?global_range.last: global_range.first + ((pos + nrange) << LOG_BLOCK);
        //Iter_t it2 = global_range.first + ((pos + nrange) << LOG_BLOCK);
        //if ((pos + nrange) == nblock) it2 = global_range.last;

        return range_it(it1, it2);
    };
    //-------------------------------------------------------------------------
    //  function : is_tail
    /// @brief indicate if a block is the tail
    /// @param pos : position of the block
    /// @return true : taiol  false : not tail
    //-------------------------------------------------------------------------
    bool is_tail(size_t pos) const
    {
        return (pos == (nblock - 1) and ntail != 0);
    };
    //-------------------------------------------------------------------------
    //  function :
    /// @brief
    /// @param
    /// @return
    //-------------------------------------------------------------------------
    void merge_range_pos(it_index itx_first, it_index itx_mid,
                         it_index itx_last);

    //-------------------------------------------------------------------------
    //  function : move_range_pos_backward
    /// @brief Move backward the elements of a range of blocks in a index
    /// @param itx_first : iterator to the position of the first block
    /// @param  itx_last : itertor to the position of the last block
    /// @param  npos : number of positions to move. Must be less than BLOCK_SIZE
    /// @return
    //-------------------------------------------------------------------------
    void move_range_pos_backward(it_index itx_first, it_index itx_last,
                                 size_t npos);

    //-------------------------------------------------------------------------
    //  function : rearrange_with_index
    /// @brief rearrange the blocks with the relative positions of the index
    /// @param
    /// @param
    /// @param
    /// @return
    //-------------------------------------------------------------------------
    void rearrange_with_index(void);

//---------------------------------------------------------------------------
};// end struct merge_block
//---------------------------------------------------------------------------
//
//############################################################################
//                                                                          ##
//           N O N     I N L I N E     F U N C T IO N S                     ##
//                                                                          ##
//############################################################################
//
//-------------------------------------------------------------------------
//  function :
/// @brief
/// @param
/// @return
//-------------------------------------------------------------------------
template<class Iter_t, class Compare, uint32_t Power2>
void merge_block<Iter_t, Compare, Power2>
::merge_range_pos(it_index itx_first, it_index itx_mid,it_index itx_last)
{
    assert((itx_last - itx_mid) >= 0 and (itx_mid - itx_first) >= 0);

    size_t nelemA = (itx_mid - itx_first), nelemB = (itx_last - itx_mid);
    if (nelemA == 0 or nelemB == 0) return;

    //-------------------------------------------------------------------
    // Create two index with the position of the blocks to merge
    //-------------------------------------------------------------------
    std::vector<size_t> indexA, indexB;
    indexA.reserve(nelemA + 1);
    indexB.reserve(nelemB);

    indexA.insert(indexA.begin(), itx_first, itx_mid);
    indexB.insert(indexB.begin(), itx_mid, itx_last);

    it_index itx_out = itx_first;
    it_index itxA = indexA.begin(), itxB = indexB.begin();
    range_it rngA, rngB;
    Iter_t itA = global_range.first, itB = global_range.first;
    bool validA = false, validB = false;

    while (itxA != indexA.end() and itxB != indexB.end())
    {   //----------------------------------------------------------------
        // Load valid ranges from the itxA and ItxB positions
        //----------------------------------------------------------------
        if (not validA)
        {
            rngA = get_range(*itxA);
            itA = rngA.first;
            validA = true;
        };
        if (not validB)
        {
            rngB = get_range(*itxB);
            itB = rngB.first;
            validB = true;
        };
        //----------------------------------------------------------------
        // If don't have merge betweeen the  blocks, pass directly the
        // position of the block to itx_out
        //----------------------------------------------------------------
        if (ptr_circ->size() == 0)
        {
            if (not cmp(*rngB.front(), *rngA.back()))
            {
                *(itx_out++) = *(itxA++);
                validA = false;
                continue;
            };
            if (cmp(*rngB.back(), *rngA.front()))
            {
                if (not is_tail(*itxB))
                    *(itx_out++) = *itxB;
                else ptr_circ->push_move_back(rngB.first, rngB.size());
                ++itxB;
                validB = false;
                continue;
            };
        };
        //----------------------------------------------------------------
        // Normal merge
        //----------------------------------------------------------------
        bool side = util::merge_circular(itA, rngA.last, itB, rngB.last,
                        *ptr_circ, cmp, itA, itB);
        if (side)
        {   // rngA is finished
            ptr_circ->pop_move_front(rngA.first, rngA.size());
            *(itx_out++) = *(itxA++);
            validA = false;
        }
        else
        {   // rngB is finished
            if (not is_tail(*itxB))
            {
                ptr_circ->pop_move_front(rngB.first, rngB.size());
                *(itx_out++) = *itxB;
            };
            ++itxB;
            validB = false;
        };
    }; // end while

    if (itxA == indexA.end())
    {   // the index A is finished
        rngB = get_range(*itxB);
        ptr_circ->pop_move_front(rngB.first, ptr_circ->size());
        while (itxB != indexB.end())
            *(itx_out++) = *(itxB++);
    }
    else
    {   // The list B is finished
        rngA = get_range(*itxA);
        if (ntail != 0 and indexB.back() == (nblock - 1)) // exist tail
        {   // add the tail block to indexA, and shift the element
            indexA.push_back(indexB.back());
            size_t numA = size_t(itA - rngA.first);
            ptr_circ->pop_move_back(rngA.first, numA);
            move_range_pos_backward(itxA, indexA.end(), ntail);
        };

        ptr_circ->pop_move_front(rngA.first, ptr_circ->size());
        while (itxA != indexA.end())
            *(itx_out++) = *(itxA++);
    };
};

//-------------------------------------------------------------------------
//  function : move_range_pos_backward
/// @brief Move backward the elements of a range of blocks in a index
/// @param itx_first : iterator to the position of the first block
/// @param  itx_last : itertor to the position of the last block
/// @param  npos : number of positions to move. Must be less than BLOCK_SIZE
/// @return
//-------------------------------------------------------------------------
template<class Iter_t, class Compare, uint32_t Power2>
void merge_block<Iter_t, Compare, Power2>
::move_range_pos_backward(it_index itx_first, it_index itx_last, size_t npos)
{
    assert((itx_last - itx_first) >= 0 and npos <= BLOCK_SIZE);

    //--------------------------------------------------------------------
    // Processing the last block. Must be ready fore to accept npos
    // elements from the upper block
    //--------------------------------------------------------------------
    range_it rng1 = get_range(*(itx_last - 1));
    assert(rng1.size() >= npos);
    if (rng1.size() > npos)
    {
        size_t nmove = rng1.size() - npos;
        util::move_backward(rng1.last, rng1.first, rng1.first + nmove);
    };
    //--------------------------------------------------------------------
    // Movement of elements between blocks
    //--------------------------------------------------------------------
    for (it_index itx = itx_last - 1; itx != itx_first;)
    {
        --itx;
        range_it rng2 = rng1;
        rng1 = get_range(*itx);
        Iter_t it_mid1 = rng1.last - npos, it_mid2 = rng2.first + npos;
        util::move_backward(it_mid2, it_mid1, rng1.last);
        util::move_backward(rng1.last, rng1.first, it_mid1);
    };
};
//-------------------------------------------------------------------------
//  function : rearrange_with_index
/// @brief rearrange the blocks with the relative positions of the index
/// @param
/// @param
/// @param
/// @return
//-------------------------------------------------------------------------
template<class Iter_t, class Compare, uint32_t Power2>
void merge_block<Iter_t, Compare, Power2>
::rearrange_with_index(void)
{   //--------------------------------------------------------------------
    //                     Code
    //--------------------------------------------------------------------
    size_t pos_dest, pos_src, pos_ini;
    size_t nelem = index.size();

    ptr_circ->clear();
    value_t * aux = ptr_circ->get_buffer();
    range_buf rng_buf(aux, aux + ptr_circ->NMAX);

    pos_ini = 0;
    while (pos_ini < nelem)
    {
        while (pos_ini < nelem and index[pos_ini] == pos_ini)
            ++pos_ini;
        if (pos_ini == nelem) return;
        pos_dest = pos_src = pos_ini;
        rng_buf = move_forward(rng_buf, get_range(pos_ini));
        pos_src = index[pos_ini];

        while (pos_src != pos_ini)
        {
            move_forward(get_range(pos_dest), get_range(pos_src));
            index[pos_dest] = pos_dest;
            pos_dest = pos_src;
            pos_src = index[pos_src];
        };
        move_forward(get_range(pos_dest), rng_buf);
        index[pos_dest] = pos_dest;
        ++pos_ini;
    };
};

//****************************************************************************
};//    End namespace common
};//    End namespace sort
};//    End namespace boost
//****************************************************************************
#endif

max_stars_repo_name: kindlychung/mediasoup-sfu-cpp

max_issues_repo_name: kindlychung/mediasoup-sfu-cpp

max_forks_repo_name: kindlychung/mediasoup-sfu-cpp


text:
/*
 * Copyright (c) 2021 Tuukka Norri
 * This code is licensed under MIT license (see LICENSE for details).
 */

#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/filter/gzip.hpp>
#include <cereal/archives/portable_binary.hpp>
#include <founder_graphs/msa_index.hh>
#include <founder_graphs/utility.hh>
#include <iostream>
#include <libbio/assert.hh>
#include <libbio/file_handle.hh>
#include <libbio/file_handling.hh>
#include "cmdline.h"

namespace fg	= founder_graphs;
namespace lb	= libbio;
namespace ios	= boost::iostreams;

namespace {

	void open_stream(lb::file_handle const &handle, lb::file_istream &stream)
	{
		ios::file_descriptor_source source(handle.get(), ios::never_close_handle);
		stream.open(source);
		stream.exceptions(std::istream::badbit);
	}

	std::size_t handle_file(std::string const &path, std::size_t const size, bool const input_is_gzipped, sdsl::bit_vector &buffer, cereal::PortableBinaryOutputArchive &archive)
	{
		std::cerr << "Handling " << path << "…" << std::flush;
		lb::file_handle handle(lb::open_file_for_reading(path));

		// Clear the gap buffer.
		if (input_is_gzipped)
		{
			if (SIZE_MAX == size)
				buffer.resize(0);
			else
				buffer.assign(size, 0);
		}
		else
		{
			// Check the file size.
			auto const [actual_size, preferred_block_size] = fg::check_file_size(handle);
			if (SIZE_MAX != size)
				libbio_always_assert_eq(size, actual_size);

			// Clear the buffer.
			libbio_assert_lt(0, actual_size);
			buffer.assign(actual_size, 0);
			libbio_assert_eq(buffer.size(), actual_size);
		}

		// Handle the sequence.
		lb::file_istream stream;
		open_stream(handle, stream);

		ios::filtering_istream in;
		if (input_is_gzipped)
			in.push(ios::gzip_decompressor());
		in.push(stream);

		char ch{};
		std::size_t i(0);
		std::size_t gap_count(0);
		while (in >> std::noskipws >> ch)
		{
			if ('-' == ch)
			{
				if (input_is_gzipped && SIZE_MAX == size)
					buffer.resize(1 + i, 0);
				buffer[i] = 1;
				++gap_count;
			}

			++i;
		}

		if (input_is_gzipped && SIZE_MAX == size)
			buffer.resize(i, 0);

		libbio_always_assert(i == buffer.size());

		// Create a compressed index and prepare rank and select support.
		fg::aligned_sequence_index seq_idx(buffer);
		seq_idx.prepare_rank_and_select_support();

		std::cerr << " handled " << i << " characters; found " << gap_count << " gap characters.\n";

		// Archive.
		archive(seq_idx);

		return i;
	}

	void build_msa_index(char const *sequence_list_path, bool const input_is_gzipped)
	{
		lb::file_istream stream;
		lb::open_file_for_reading(sequence_list_path, stream);

		std::vector <std::string> paths;
		std::string line;
		std::size_t file_size{SIZE_MAX};
		while (std::getline(stream, line))
			paths.push_back(line);

		// Prepare the output archive.
		cereal::PortableBinaryOutputArchive archive(std::cout);
		{
			std::size_t const size(paths.size());
			archive(cereal::make_size_tag(size));
		}

		// Handle the inputs.
		sdsl::bit_vector buffer;
		for (auto const &path : paths)
			file_size = handle_file(path, file_size, input_is_gzipped, buffer, archive);

		std::cout << std::flush;
	}
}

int main(int argc, char **argv)
{
#ifndef NDEBUG
	std::cerr << "Assertions have been enabled." << std::endl;
#endif

	gengetopt_args_info args_info;
	if (0 != cmdline_parser(argc, argv, &args_info))
		std::exit(EXIT_FAILURE);

	std::ios_base::sync_with_stdio(false);	// Don't use C style IO after calling cmdline_parser.
	std::cin.tie(nullptr);					// We don't require any input from the user.

	build_msa_index(args_info.sequence_list_arg, args_info.gzip_input_flag);

	return EXIT_SUCCESS;
}

ext: cc

max_stars_repo_name: tsnorri/founder-graphs-semi-repeat-free

max_issues_repo_name: tsnorri/founder-graphs-semi-repeat-free

max_forks_repo_name: tsnorri/founder-graphs-semi-repeat-free


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

ext: cpp


text:
/*!
@file
Forward declares `boost::hana::union_`.

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

#ifndef BOOST_HANA_FWD_UNION_HPP
#define BOOST_HANA_FWD_UNION_HPP

#include <boost/hana/config.hpp>
#include <boost/hana/core/when.hpp>

BOOST_HANA_NAMESPACE_BEGIN
    //! Returns the union of two sets.
    //! @relates hana::set
    //!
    //! Given two sets `xs` and `ys`, `union_(xs, ys)` is a new set containing
    //! all the elements of `xs` and all the elements of `ys`, without
    //! duplicates. For any object `x`, the following holds:
    //! @code
    //!     x ^in^ union_(xs, ys) if and only if x ^in^ xs || x ^in^ ys
    //! @endcode
    //!
    //!
    //! @param xs, ys
    //! Two sets to compute the union of.
    //!
    //!
    //! Example
    //! -------
    //! @include example/union.cpp
#ifdef BOOST_HANA_DOXYGEN_INVOKED
    constexpr auto union_ = [](auto&& xs, auto&& ys) {
        return tag-dispatched;
    };
#else
    template <typename S, typename = void>
    struct union_impl : union_impl<S, when<true>> { };

    struct union_t {
        template <typename Xs, typename Ys>
        constexpr auto operator()(Xs&& xs, Ys&& ys) const;
    };

    constexpr union_t union_{};
#endif
BOOST_HANA_NAMESPACE_END

#endif // !BOOST_HANA_FWD_UNION_HPP

ext: hpp

max_stars_repo_name: rudylee/expo

max_issues_repo_name: rudylee/expo

max_forks_repo_name: rudylee/expo


text:
#include <memo/silo/Strip.hh>

#include <elle/algorithm.hh>

#include <memo/model/Address.hh>

#include <boost/algorithm/string.hpp>

#include <elle/factory.hh>
#include <elle/reactor/Scope.hh>

namespace memo
{
  namespace silo
  {
    Strip::Strip(std::vector<std::unique_ptr<Silo>> backend)
      : _backend(std::move(backend))
    {
      // This assumes that the metrics are already correct in the
      // "backends".
      for (auto const& b: _backend)
      {
        _usage += b->usage();
        _block_count += b->block_count();
      }
    }

    elle::Buffer
    Strip::_get(Key k) const
    {
      return _storage_of(k).get(k);
    }

    int
    Strip::_set(Key k, elle::Buffer const& value, bool insert, bool update)
    {
      return _storage_of(k).set(k, value, insert, update);
    }

    int
    Strip::_erase(Key k)
    {
      return _storage_of(k).erase(k);
    }

    namespace
    {
      /// The sum of the digits of this address.
      int
      sum(Key k)
      {
        int res = 0;
        for (auto c: k.value())
          res += c;
        return res;
      }
    }

    Silo&
    Strip::_storage_of(Key k) const
    {
      return *_backend[sum(k) % _backend.size()];
    }

    std::vector<Key>
    Strip::_list()
    {
      auto res = std::vector<Key>{};
      for (auto const& b: _backend)
        elle::push_back(res, b->list());
      return res;
    }

    static
    std::unique_ptr<Silo>
    make(std::vector<std::string> const& args)
    {
      auto backends = std::vector<std::unique_ptr<Silo>>{};
      for (unsigned int i = 0; i < args.size(); i += 2)
        backends.emplace_back(instantiate(args[i], args[i+1]));
      return std::make_unique<Strip>(std::move(backends));
    }

    StripSiloConfig::StripSiloConfig(
      Silos storages,
      boost::optional<int64_t> capacity,
      boost::optional<std::string> description)
      : SiloConfig(
          "multi-storage", std::move(capacity), std::move(description))
      , storage(std::move(storages))
    {}

    StripSiloConfig::StripSiloConfig(elle::serialization::SerializerIn& s)
      : SiloConfig(s)
      , storage(s.deserialize<Silos>("backend"))
    {}

    void
    StripSiloConfig::serialize(elle::serialization::Serializer& s)
    {
      SiloConfig::serialize(s);
      s.serialize("backend", this->storage);
    }

    std::unique_ptr<memo::silo::Silo>
    StripSiloConfig::StripSiloConfig::make()
    {
      std::vector<std::unique_ptr<memo::silo::Silo>> s;
      for(auto const& c: storage)
        s.push_back(c->make());
      return std::make_unique<memo::silo::Strip>(
        std::move(s));
    }

    static const elle::serialization::Hierarchy<SiloConfig>::
    Register<StripSiloConfig>
    _register_StripSiloConfig("strip");
  }
}

FACTORY_REGISTER(memo::silo::Silo, "strip", &memo::silo::make);

max_stars_repo_name: infinit/memo

max_issues_repo_name: infinit/memo

max_forks_repo_name: infinit/memo


text:
/* Copyright (c) 2015 Convey Computer Corporation
 *
 * This file is part of the OpenHT toolset located at:
 *
 * https://github.com/TonyBrewer/OpenHT
 *
 * Use and distribution licensed under the BSD 3-clause license.
 * See the LICENSE file for the complete license text.
 */

#include <algorithm>
#include <functional>
#include <numeric>
#include <iostream>
#include <vector>
#include <boost/foreach.hpp>

#include "HtSageUtils.h"
#include "RewriteControlFlow.h"

#define foreach BOOST_FOREACH  // Replace with range-based for when C++'11

// Build: "if (cond) { goto label; }".  (or !cond).
static SgIfStmt *makeIfWithGoto(SgExpression *cond, SgLabelStatement *labStmt,
                                bool negateCond)
{
  SgExpression *newcond = SageInterface::deepCopy(cond);
  if (negateCond) {
    newcond = SageBuilder::buildNotOp(newcond);
  }
  SgIfStmt *ifStmt = SageBuilder::buildIfStmt(
      SageBuilder::buildExprStatement(newcond),
      SageBuilder::buildBasicBlock(SageBuilder::buildGotoStatement(labStmt)),
      0 /* false body empty */);
  ifStmt->addNewAttribute("dont_process", new DontProcessAttribute());
  return ifStmt;
}

// Rewrite:
//    ...
//   continue;
//    ...
// As:
//   <<incr>>                 // (for-loop only)
//   goto loop_top;           // for-loop, while-loop, do-while-loop
//
static void rewriteActiveContinueStmts(SgBasicBlock *body,
                                       SgLabelStatement *labelTopStmt,
                                       SgExpression *incrExpr)
{
  std::vector<SgContinueStmt *> cl = SageInterface::findContinueStmts(body);
  foreach (SgContinueStmt *oldContinue, cl) {
    if (incrExpr) {
      SgExpression *copyIncr = SageInterface::deepCopy(incrExpr);
      SgExprStatement *newIncr = SageBuilder::buildExprStatement(copyIncr);
      SageInterface::insertStatementBefore(oldContinue, newIncr);
    }
    SgGotoStatement *ngoto = SageBuilder::buildGotoStatement(labelTopStmt);
    SageInterface::replaceStatement(oldContinue, ngoto, true);
  }
}

//
// Rewrite 'break' to exit the current loop or switch scope.
//
static void rewriteActiveBreakStmts(SgBasicBlock *body,
                                    SgLabelStatement *labelExitStmt)
{
  std::vector<SgBreakStmt *> bl = SageInterface::findBreakStmts(body);
  foreach (SgBreakStmt *oldBreak, bl) {
    SgGotoStatement *ngoto = SageBuilder::buildGotoStatement(labelExitStmt);
    SageInterface::replaceStatement(oldBreak, ngoto, true);
  }
}

//
// Rewrite:                            OR
//  for (init; cond; incr) {                              while (cond) {
//    body                                                  body
//  }                                                     }
//  ...                                                   ...
//
// As:
//
//  {
//   <<init>>               // for-loop only
//   loop_top:
//   if (!<<cond>>) {
//     goto loop_exit;
//   }
//   <<body>>
//   <<incr>>               // for-loop only
//   goto loop_top;
//   loop_exit:
//     ;
//  }
//  ...
//
// The remaining outermost braces (SgBasicBlock) will be removed in
// a subsequent pass.
//
static void rewriteTopTestedLoop_Common(SgScopeStatement *S,
                           SgBasicBlock *forInitBlock, SgExpression *incrExpr)
{
  SgScopeStatement *proc = SageInterface::getEnclosingProcedure(S);
  SgBasicBlock *body = isSgBasicBlock(SageInterface::getLoopBody(S));
  assert(body && "expected SgBasicBlock-- not normalized?");

  // Construct the label statements.
  int ln = ++SageInterface::gensym_counter;
  SgLabelStatement *labelTopStmt = HtSageUtils::makeLabelStatement("loop_top", ln, proc);
  SgLabelStatement *labelExitStmt = HtSageUtils::makeLabelStatement("loop_exit", ln, proc);

  // Insert the "<<incr>>" expression (for-loops only).
  if (incrExpr) {
    SageInterface::appendStatement(SageBuilder::buildExprStatement(incrExpr),
        body);
  }

  // Build and insert "goto loop_top; loop_exit:".
  SgStatement *newGotoStmt = SageBuilder::buildGotoStatement(labelTopStmt);
  SageInterface::appendStatement(newGotoStmt, body);
  SageInterface::appendStatement(labelExitStmt, body);

  // Build "if (!<<cond>>) { goto loop_exit; }" subtree.
  SgStatement *condStmt = SageInterface::getLoopCondition(S);
  assert(condStmt && "loop cond not SgStatement?");
  SgExpression *cexpr = 0;
  if (isSgNullStatement(condStmt)) {
    cexpr = SageBuilder::buildBoolValExp(true);
  } else {
    assert(isSgExprStatement(condStmt) && "loop cond not SgExprStatement?");
    cexpr = isSgExprStatement(condStmt)->get_expression();
  }
  SgStatement *ifstmt = makeIfWithGoto(cexpr, labelExitStmt, true /* neg */);
  SageInterface::prependStatement(ifstmt, body);

  // Insert "loop_top:" statement.
  SageInterface::prependStatement(labelTopStmt, body);

  // Insert "<<init>>" statement (for-loop only).
  if (forInitBlock) {
    SageInterface::prependStatement(forInitBlock, body);
  }

  // Move preprocessor info from the original ForStmt to the first
  // statement (a new NullStmt anchor).
  // TODO: Only does PreprocessingInfo::before.
  SgStatement *newFirstStmt = SageBuilder::buildNullStatement();
  SageInterface::prependStatement(newFirstStmt, body);
  SageInterface::movePreprocessingInfo(S, newFirstStmt,
      PreprocessingInfo::before);

  // Move preprocessor info (position PreprocessingInfo::inside) from the
  // original body block to the last statement in the loop (i.e., the
  // new goto statement, since the loop exit label is logically outside
  // the loop).  These directives would otherwise disappear after
  // flattenBlocks.
  SageInterface::movePreprocessingInfo(body, newGotoStmt,
      PreprocessingInfo::inside, PreprocessingInfo::after);

  // Disconnect body from old loop, and replace loop in parent with body.
  SageInterface::setLoopBody(S, SageBuilder::buildNullStatement());
  isSgStatement(S->get_parent())->replace_statement(S, body);

  rewriteActiveContinueStmts(body, labelTopStmt, incrExpr);
  rewriteActiveBreakStmts(body, labelExitStmt);
}

void RewriteControlFlowPass1Visitor::visitSgForStatement(SgForStatement *S)
{
  // Move the init statements into a new block and disconnect from loop.
  SgBasicBlock *newInitBlock = SageBuilder::buildBasicBlock();
  SgForInitStatement *inits = S->get_for_init_stmt();
  SgStatementPtrList &initStmts = inits->get_init_stmt();
  for (size_t i = 0; i < initStmts.size(); i++) {
    SageInterface::appendStatement(initStmts[i], newInitBlock);
    assert(initStmts[i]->get_parent() == newInitBlock);
  }
  initStmts.clear();

  // Disconnect incr expression from loop.
  SgExpression *incr = S->get_increment();
  S->set_increment(0);
  incr->set_parent(0);

  rewriteTopTestedLoop_Common(S, newInitBlock, incr);
}

void RewriteControlFlowPass1Visitor::visitSgWhileStmt(SgWhileStmt *S)
{
  rewriteTopTestedLoop_Common(S, 0, 0);
}

//
// Rewrite:
//  do {
//    body
//  } while (cond);
//  ...
//
// As:
//
//  {
//   loop_top:
//   <<body>>
//   if (<<cond>>) {
//     goto loop_top;
//   }
//   loop_exit:                // Target only for 'break' statements.
//  }
//  ...
//
// The remaining outermost braces (SgBasicBlock) will be removed in
// a subsequent pass.
//
void RewriteControlFlowPass1Visitor::visitSgDoWhileStmt(SgDoWhileStmt *S)
{
  SgScopeStatement *proc = SageInterface::getEnclosingProcedure(S);
  SgBasicBlock *body = isSgBasicBlock(SageInterface::getLoopBody(S));
  assert(body && "expected SgBasicBlock-- not normalized?");

  // Construct and insert the label statement.
  int ln = ++SageInterface::gensym_counter;
  SgLabelStatement *labelTopStmt = HtSageUtils::makeLabelStatement("loop_top", ln, proc);
  SgLabelStatement *labelExitStmt = HtSageUtils::makeLabelStatement("loop_exit", ln, proc);
  SageInterface::prependStatement(labelTopStmt, body);

  // Build "if (<<cond>>) { goto loop_top; }" subtree.
  SgExprStatement *cond = isSgExprStatement(S->get_condition());
  assert(cond && "expected SgExprStatement for do_while condition");
  SgStatement *ifstmt = makeIfWithGoto(cond->get_expression(), labelTopStmt,
    false /* negate cond? */);
  SageInterface::appendStatement(ifstmt, body);
  SageInterface::appendStatement(labelExitStmt, body);

  // Move preprocessor info from the original DoWhileStmt to the first
  // statement (a new NullStmt anchor).
  // TODO: Only does PreprocessingInfo::before.
  SgStatement *newFirstStmt = SageBuilder::buildNullStatement();
  SageInterface::prependStatement(newFirstStmt, body);
  SageInterface::movePreprocessingInfo(S, newFirstStmt,
      PreprocessingInfo::before);

  // Move preprocessor info (position PreprocessingInfo::inside) from the
  // original body block to the last statement in the loop (i.e., a new
  // anchor just before the loop exit label).
  // These directives would otherwise disappear after flattenBlocks.
  SgStatement *anchor = SageBuilder::buildNullStatement();
  SageInterface::insertStatementBefore(labelExitStmt, anchor);
  SageInterface::movePreprocessingInfo(body, anchor,
      PreprocessingInfo::inside, PreprocessingInfo::after);

  // Disconnect body from old while, and replace while in parent with body.
  SageInterface::setLoopBody(S, SageBuilder::buildNullStatement());
  isSgStatement(S->get_parent())->replace_statement(S, body);

  rewriteActiveContinueStmts(body, labelTopStmt, 0);
  rewriteActiveBreakStmts(body, labelExitStmt);
}

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

std::map<SgNode *, bool> nodeOpensState;

bool AssignNodeOpensState::evaluateSynthesizedAttribute(SgNode *n,
    SynthesizedAttributesList childAttributes)
{
  bool opensState = std::accumulate(childAttributes.begin(),
      childAttributes.end(), false, std::logical_or<bool>());

  VariantT t = n->variantT();
  opensState |= (t == V_SgLabelStatement || t == V_SgSwitchStatement
      || t == V_SgGotoStatement);

  nodeOpensState[n] = opensState;
  return opensState;
}

//
// This is the fully general IfStmt rewriter which introduces new
// states for each branch and the join point.  This transformation
// is only necessary if one or both branches themselves introduce
// new states.  Simple 'if' statements can be left untranslated.
//
// Rewrite:
//   if (c) {
//     <<then code>>
//   } else {
//     <<else code>>
//   }
//   ...
// As:
//       if (!( c )) {
//         goto if_else;
//       }
//       <<then code>>
//       goto if_join;
//   if_else:
//       <<else code>>
//       /* goto if_join; */
//   if_join:
//       ...
//
// If there is no 'else' clause, the IF_ELSE section is omitted,
// and the conditional branches to the IF_JOIN instead.
//
void RewriteControlFlowPass2Visitor::visitSgIfStmt(SgIfStmt *S)
{
  // Don't translate unless children opened states.
  assert(nodeOpensState.find(S) != nodeOpensState.end());
  if (nodeOpensState[S] == false
      || getDontProcessAttribute(S)) {
    return;
  }

  SgScopeStatement *proc = SageInterface::getEnclosingProcedure(S);
  SgBasicBlock *trueBody = isSgBasicBlock(S->get_true_body());
  SgBasicBlock *falseBody = isSgBasicBlock(S->get_false_body());
  assert(trueBody && "expected SgBasicBlock-- not normalized?");
  assert(falseBody && "expected SgBasicBlock-- not normalized?");

  SgBasicBlock *newBlock = SageBuilder::buildBasicBlock();

  bool hasElse = falseBody->get_statements().size() > 0;

  // Construct the label statements.
  int ln = ++SageInterface::gensym_counter;
  SgLabelStatement *labelElseStmt = HtSageUtils::makeLabelStatement("if_else", ln, proc);
  SgLabelStatement *labelJoinStmt = HtSageUtils::makeLabelStatement("if_join", ln, proc);

  // Build "if (!<<cond>>) { goto if_else; }" subtree.
  SgExprStatement *cond = isSgExprStatement(S->get_conditional());
  assert(cond && "expected SgExprStatement for do_while condition");
  SgStatement *ifstmt = makeIfWithGoto(cond->get_expression(),
      (hasElse ? labelElseStmt : labelJoinStmt), true /* neg */);
  SageInterface::appendStatement(ifstmt, newBlock);

  SageInterface::appendStatement(trueBody, newBlock);
  if (hasElse) {
    SageInterface::appendStatement(
        SageBuilder::buildGotoStatement(labelJoinStmt), newBlock);
    SageInterface::appendStatement(labelElseStmt, newBlock);
    SageInterface::appendStatement(falseBody, newBlock);
  }
  SageInterface::appendStatement(labelJoinStmt, newBlock);

  // Move preprocessor info from the original IfStmt to the first new
  // statement.  It appears that ROSE currently only attaches preproc info
  // to an IfStmt using the relative position 'before', so that we do not
  // need to special case the other possibilities (and all the info can be
  // attached in the same position to the new first statement).
  SageInterface::movePreprocessingInfo(S, ifstmt);

  // Replace old 'if' in parent with new body.
  S->set_true_body(0);
  S->set_false_body(0);
  isSgStatement(S->get_parent())->replace_statement(S, newBlock);
}

void RewriteControlFlowPass2Visitor::visitSgSwitchStatement(SgSwitchStatement *S)
{
  // TODO: use schedule information to decide whether or not to translate.

  SgScopeStatement *proc = SageInterface::getEnclosingProcedure(S);
  SgBasicBlock *switchBody = isSgBasicBlock(S->get_body());
  assert(switchBody && "expected block for switch body");
  SgBasicBlock *newContainer = SageBuilder::buildBasicBlock();

  // Replace old switch in parent with a new block containing copy of
  // switch (since we need to add statements AFTER the switch).
  SgSwitchStatement *newS = SageBuilder::buildSwitchStatement(
      S->get_item_selector(), switchBody);
  S->set_item_selector(0);
  S->set_body(0);
  isSgStatement(S->get_parent())->replace_statement(S, newContainer);
  S = newS;
  SageInterface::appendStatement(S, newContainer);

  // Insert new join label after switch statement.
  int ln = ++SageInterface::gensym_counter;
  SgLabelStatement *ljoin = HtSageUtils::makeLabelStatement("switch_join", ln, proc);
  SageInterface::insertStatementAfter(S, ljoin);

  // Rewrite the break statements before outlining the case bodies.
  rewriteActiveBreakStmts(switchBody, ljoin);

  // Outline case bodies.
  bool hasDefault = false;
  SgBasicBlock *outlineBlock = SageBuilder::buildBasicBlock();
  foreach (SgStatement *currStmt, switchBody->get_statements()) {
    SgCaseOptionStmt *thisCase = isSgCaseOptionStmt(currStmt);
    SgDefaultOptionStmt *thisDefault = isSgDefaultOptionStmt(currStmt);
    SgBasicBlock *optionBody = 0;
    SgBasicBlock *newOptionBody = SageBuilder::buildBasicBlock();
    if (thisCase) {
      optionBody = isSgBasicBlock(thisCase->get_body());
      assert(optionBody && "expected block for case body");
      thisCase->set_body(newOptionBody);
      newOptionBody->set_parent(thisCase);
    } else if (thisDefault) {
      optionBody = isSgBasicBlock(thisDefault->get_body());
      assert(optionBody && "expected block for default body");
      thisDefault->set_body(newOptionBody);
      newOptionBody->set_parent(thisDefault);
      hasDefault = true;
    } else {
      assert(0);
    }
    int ln = ++SageInterface::gensym_counter;
    SgName lname = (thisCase ? "switch_case" : "switch_default");
    SgLabelStatement *lstmt = HtSageUtils::makeLabelStatement(lname, ln, proc);
    SageInterface::appendStatement(SageBuilder::buildGotoStatement(lstmt),
        newOptionBody);

    SageInterface::appendStatement(lstmt, outlineBlock);
    SageInterface::appendStatement(optionBody, outlineBlock);
  }

  if (hasDefault == false) {
    // Add a default case that jumps to the join if user didn't have one.
    SageInterface::appendStatement(SageBuilder::buildDefaultOptionStmt(
        SageBuilder::buildBasicBlock(SageBuilder::buildGotoStatement(ljoin))),
        switchBody);
  }

  // Insert outlined case bodies just after original switch.
  SageInterface::insertStatementAfter(S, outlineBlock);
}

max_stars_repo_name: TonyBrewer/OpenHT

max_issues_repo_name: PacificBiosciences/OpenHT

max_forks_repo_name: TonyBrewer/OpenHT


text:
//---------------------------------------------------------------------------//
//!
//! \file   MonteCarlo_HardElasticElectronScatteringDistribution.hpp
//! \author Luke Kersting
//! \brief  The electron hard elastic scattering distribution base class
//!
//---------------------------------------------------------------------------//

#ifndef MONTE_CARLO_HARD_ELASTIC_ELECTRON_SCATTERING_DISTRIBUTION_HPP
#define MONTE_CARLO_HARD_ELASTIC_ELECTRON_SCATTERING_DISTRIBUTION_HPP

// Std Lib Includes
#include <limits>

// Boost Includes
#include <boost/function.hpp>
#include <boost/bind.hpp>

// Trilinos Includes
#include <Teuchos_Array.hpp>
#include <Teuchos_RCP.hpp>

// FRENSIE Includes
#include "MonteCarlo_ElectronState.hpp"
#include "MonteCarlo_ParticleBank.hpp"
#include "MonteCarlo_ElectronScatteringDistribution.hpp"
#include "MonteCarlo_AdjointElectronScatteringDistribution.hpp"
#include "Utility_TabularOneDDistribution.hpp"

namespace MonteCarlo{

//! The scattering distribution base class
class HardElasticElectronScatteringDistribution : public ElectronScatteringDistribution,
                                                  public AdjointElectronScatteringDistribution
{

public:

  //! Typedef for the  elastic distribution
  typedef Teuchos::Array<Utility::Pair< double,
		       Teuchos::RCP<const Utility::TabularOneDDistribution> > >
  ElasticDistribution;

  //! Constructor
  HardElasticElectronScatteringDistribution(
                 const int atomic_number,
                 const ElasticDistribution& elastic_scattering_distribution);

  //! Destructor
  virtual ~HardElasticElectronScatteringDistribution()
  { /* ... */ }

  //! Evaluate the PDF
  double evaluatePDF( const double incoming_energy,
                      const double scattering_angle_cosine ) const;

  //! Evaluate the PDF
  double evaluatePDF( const unsigned incoming_energy_bin,
                      const double scattering_angle_cosine ) const;

  //! Evaluate the CDF
  double evaluateCDF( const double incoming_energy,
                      const double scattering_angle_cosine ) const;

  //! Return the energy at a given energy bin
  double getEnergy( const unsigned energy_bin ) const;

  // Evaluate the analytical Screened Rutherford PDF
  double evaluateScreenedRutherfordPDF(
                      const double incoming_energy,
                      const long double scattering_angle_cosine ) const;

  //! Evaluate the screened Rutherford cross section ratio above the cutoff mu
  double evaluateScreenedRutherfordCrossSectionRatio(
                                  const double incoming_energy ) const;

  //! Sample an outgoing energy and direction from the distribution
  void sample( const double incoming_energy,
               double& outgoing_energy,
               double& scattering_angle_cosine ) const;

  //! Sample an outgoing energy and direction and record the number of trials
  void sampleAndRecordTrials( const double incoming_energy,
                              double& outgoing_energy,
                              double& scattering_angle_cosine,
                              unsigned& trials ) const;

  //! Randomly scatter the electron
  void scatterElectron( ElectronState& electron,
                        ParticleBank& bank,
                        SubshellType& shell_of_interaction ) const;

  //! Randomly scatter the adjoint electron
  void scatterAdjointElectron( AdjointElectronState& adjoint_electron,
                               ParticleBank& bank,
                               SubshellType& shell_of_interaction ) const;

//protected:

   //! Sample an outgoing direction from the distribution
  void sampleAndRecordTrialsImpl( const double incoming_energy,
                                  double& scattering_angle_cosine,
                                  unsigned& trials ) const;

  //! Evaluate Moliere's atomic screening constant at the given electron energy
  double evaluateMoliereScreeningConstant( const double energy ) const;

  //! Evaluate the scattering angle from the analytical screened Rutherford function
  double evaluateScreenedScatteringAngle( const double energy ) const;

private:

  // Cutoff angle cosine between the distribution and analytical screened Rutherford function
  static double s_rutherford_cutoff;

  // Difference btw cutoff angle cosine and forward peak (mu = 1)
  static double s_delta_cutoff;

  // The fine structure constant (fsc) squared
  static double s_fine_structure_const_squared;

  // A parameter for moliere's screening factor  (1/2*(fsc/0.885)**2)
  static double s_screening_param1;

  // Atomic number (Z) of the target atom
  int d_atomic_number;

  // Atomic number (Z) of the target atom to the 2/3 power (Z^2/3)
  double d_Z_two_thirds_power;

  // A parameter for moliere's screening factor (3.76*fsc**2*Z**2)
  double d_screening_param2;

  // elastic scattering distribution without forward screening data
  ElasticDistribution d_elastic_scattering_distribution;
};

} // end MonteCarlo namespace

#endif // end MONTE_CARLO_HARD_ELASTIC_ELECTRON_SCATTERING_DISTRIBUTION_HPP

//---------------------------------------------------------------------------//
// end MonteCarlo_HardElasticElectronScatteringDistribution.hpp
//---------------------------------------------------------------------------//


text: #include <boost/qvm/gen/vec_assign4.hpp>

max_stars_repo_name: miathedev/BoostForArduino

max_issues_repo_name: miathedev/BoostForArduino

max_forks_repo_name: miathedev/BoostForArduino


text:
//
// Copyright 2007-2008 Christian Henning, Andreas Pokorny, Lubomir Bourdev
//
// Distributed under the Boost Software License, Version 1.0
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//
#ifndef BOOST_GIL_EXTENSION_IO_TIFF_DETAIL_SUPPORTED_TYPES_HPP
#define BOOST_GIL_EXTENSION_IO_TIFF_DETAIL_SUPPORTED_TYPES_HPP

#include <boost/gil/extension/io/tiff/tags.hpp>

#include <boost/gil/channel.hpp>
#include <boost/gil/color_base.hpp>
#include <boost/gil/io/base.hpp>

#include <type_traits>

namespace boost{ namespace gil {

namespace detail {

// Read support

// TIFF virtually supports everything
struct tiff_read_support : read_support_true
{};

// Write support

struct tiff_write_support : write_support_true
{};

} // namespace detail

template<typename Pixel>
struct is_read_supported<Pixel, tiff_tag>
    : std::integral_constant<bool, detail::tiff_read_support::is_supported>
{};

template<typename Pixel>
struct is_write_supported<Pixel, tiff_tag>
    : std::integral_constant<bool, detail::tiff_write_support::is_supported>
{};

}} // namespace boost::gil

#endif


text:
/*
@copyright Louis Dionne 2014
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
 */

#include <boost/hana/functional.hpp>

#include <boost/hana/detail/assert.hpp>
#include <boost/hana/detail/constexpr.hpp>
using namespace boost::hana;

BOOST_HANA_CONSTEXPR_LAMBDA auto f = [](auto ...xs) {
    return sizeof...(xs);
};

int main() {
    BOOST_HANA_CONSTEXPR_ASSERT(curry<0>(f)() == f());

    BOOST_HANA_CONSTEXPR_ASSERT(curry<1>(f)(1) == f(1));

    BOOST_HANA_CONSTEXPR_ASSERT(curry<2>(f)(1)('2') == f(1, '2'));
    BOOST_HANA_CONSTEXPR_ASSERT(curry<2>(f)(1, '2') == f(1, '2'));

    BOOST_HANA_CONSTEXPR_ASSERT(curry<3>(f)(1)('2')(3.3) == f(1, '2', 3.3));
    BOOST_HANA_CONSTEXPR_ASSERT(curry<3>(f)(1)('2', 3.3) == f(1, '2', 3.3));
    BOOST_HANA_CONSTEXPR_ASSERT(curry<3>(f)(1, '2')(3.3) == f(1, '2', 3.3));
    BOOST_HANA_CONSTEXPR_ASSERT(curry<3>(f)(1, '2', 3.3) == f(1, '2', 3.3));

    // Make sure curry is idempotent; this is important because it allows
    // currying a function in generic contexts where it is unknown whether
    // the function is already curried.
    BOOST_HANA_CONSTEXPR_ASSERT(curry<0>(curry<0>(f))() == f());

    BOOST_HANA_CONSTEXPR_ASSERT(curry<1>(curry<1>(f))(1) == f(1));

    BOOST_HANA_CONSTEXPR_ASSERT(curry<2>(curry<2>(f))(1)('2') == f(1, '2'));
    BOOST_HANA_CONSTEXPR_ASSERT(curry<2>(curry<2>(f))(1, '2') == f(1, '2'));

    BOOST_HANA_CONSTEXPR_ASSERT(curry<3>(curry<3>(f))(1)('2')(3.3) == f(1, '2', 3.3));
    BOOST_HANA_CONSTEXPR_ASSERT(curry<3>(curry<3>(f))(1)('2', 3.3) == f(1, '2', 3.3));
    BOOST_HANA_CONSTEXPR_ASSERT(curry<3>(curry<3>(f))(1, '2')(3.3) == f(1, '2', 3.3));
    BOOST_HANA_CONSTEXPR_ASSERT(curry<3>(curry<3>(f))(1, '2', 3.3) == f(1, '2', 3.3));
}

max_stars_repo_name: rbock/hana

max_issues_repo_name: rbock/hana

max_forks_repo_name: rbock/hana


text:
#include "base58.h"
#include "contract/rpctoken.h"
#include "init.h"
#include "main.h"
#include "rpc/server.h"
#include "script/script.h"
#include "script/script_error.h"
#include "script/sign.h"
#include "script/standard.h"
#include "sync.h"
#include "dstencode.h"
#include "txmempool.h"
#include "core_io.h"
#include "contract/tokentxcheck.h"
#include "contract/tokeninterpreter.h"
#ifdef ENABLE_WALLET
#include "wallet/wallet.h"
#endif
#include <vector>
#include <boost/algorithm/string.hpp>
#include <boost/assign/list_of.hpp>
#include "contract/contractconfig.h"
#include "contract/contracterror.h"
#include "contract/contractio.h"
#include "contract/contracttally.h"

static void TxInErrorToJSON(const CTxIn &txin, UniValue &vErrorsRet, const std::string &strMessage)
{
    UniValue entry(UniValue::VOBJ);
    entry.push_back(Pair("txid", txin.prevout.hash.ToString()));
    entry.push_back(Pair("vout", (uint64_t)txin.prevout.n));
    entry.push_back(Pair("scriptSig", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())));
    entry.push_back(Pair("sequence", (uint64_t)txin.nSequence));
    entry.push_back(Pair("error", strMessage));
    vErrorsRet.push_back(entry);
}

UniValue tokenmint(const UniValue& params, bool fHelp)
{
	if (fHelp || params.size() != 3)
		throw std::runtime_error(
                "tokenmint \"(feetxid,vout)\" \"(witnesstxid,vout)\" {\"tokenname\" \"tokenamount\" \"address\"}\n"

				"\nArguments:\n"
                "1. (feetxid,vout)                                \n"
                "2. (witnesstxid,vout)                            \n"
                "3. {\"tokenname\" \"tokenamount\" \"address\"}   \n"

				"\nResult:\n"
				"\"txid\"                 (string) the hash of mint w transaction\n"

				"\nExamples\n"
                +HelpExampleCli("tokenmint", "\"[{\\\"txid\\\":\\\"feetxid\\\",\\\"vout\\\":0}]\" \"{\\\"witnesstxid\\\":0}\" \"{\\\"name\\\":\\\"token_name\\\" ,\\\"amount\\\":10000,\\\"address\\\":\\\"xxxxxx\\\"}\"")
                +HelpExampleCli("tokenmint", "\"[{\\\"txid\\\":\\\"feetxid\\\",\\\"vout\\\":0}]\" \"{\\\"witnesstxid\\\":0}\" \"{\\\"name\\\":\\\"token_name\\\" ,\\\"amount\\\":10000,\\\"address\\\":\\\"xxxxxx\\\"}\"")
                );

    UniValue inputs = params[0].get_array();
    UniValue witness_utxo = params[1].get_obj();
    UniValue token_sendTo = params[2].get_obj();

    CMutableTransaction rawTx;

    for (unsigned int idx = 0; idx < inputs.size(); idx++)
    {
        const UniValue& input = inputs[idx];
        const UniValue& o = input.get_obj();
        uint256 txid = ParseHashO(o, "txid");

        const UniValue& vout_v = find_value(o, "vout");
        if (!vout_v.isNum())
            throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing vout key");

        int nOutput = vout_v.get_int();
        if (nOutput < 0)
            throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout must be positive");

        uint32_t nSequence = (rawTx.nLockTime ? std::numeric_limits<uint32_t>::max() - 1 : std::numeric_limits<uint32_t>::max());

        // set the sequence number if passed in the parameters object
        const UniValue& sequenceObj = find_value(o, "sequence");
        if (sequenceObj.isNum()) {
            int64_t seqNr64 = sequenceObj.get_int64();
            if (seqNr64 < 0 || seqNr64 > std::numeric_limits<uint32_t>::max())
                throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, sequence number is out of range");
            else
                nSequence = (uint32_t)seqNr64;
        }

        CTxIn in(COutPoint(txid, nOutput), CScript(), nSequence);
        rawTx.vin.push_back(in);
    }

    int error_token = CheckTokenVin(witness_utxo);
    if ( error_token )
    {
        throw JSONRPCError(error_token, std::string("Token vin error: "));
    }

    CScript script_token_tx;
    script_token_tx << OP_RETURN << TOKEN_ISSUE;

    std::vector<std::string> token_witness_list  = witness_utxo.getKeys();
    for (unsigned int i =0; i<token_witness_list.size(); i++)
    {
        std::string witness_txid = token_witness_list.at(i);
        int vin_pos = witness_utxo[witness_txid].get_int();
        if ( !IsTxidUnspent(witness_txid,(unsigned int)vin_pos))
        {
            throw JSONRPCError(-8, std::string("witness id  has spent"));
        }
        script_token_tx << ToByteVector(witness_txid);
        //int vin_pos = witness_utxo[witness_txid].get_int();
        script_token_tx << vin_pos ;
    }

    std::vector<std::string> addrList = token_sendTo.getKeys();
    BOOST_FOREACH(const std::string& name_, addrList)
    {
        if (name_ == "name")
        {
            script_token_tx << ToByteVector(token_sendTo[name_].getValStr());
        }
        else if (name_ == "amount")
        {
            CAmount amount  = token_sendTo[name_].get_int64();
            script_token_tx << amount;
        }
        else if (name_ == "address")
        {
            std::string addr = token_sendTo[name_].getValStr();
            CTxDestination destination = DecodeDestination(addr);
            if (!IsValidDestination(destination))
            {
                throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, std::string("Invalid Bitcoin address: ") + addr);
            }
            script_token_tx << ToByteVector(addr);
        }

    }

    CTxOut out(0, script_token_tx);
    rawTx.vout.push_back(out);

// sign tx
#ifdef ENABLE_WALLET
    LOCK2(cs_main, pwalletMain ? &pwalletMain->cs_wallet : NULL);
#else
    LOCK(cs_main);
#endif

    std::vector<CMutableTransaction> txVariants;
    txVariants.push_back(rawTx);

    if (txVariants.empty())
        throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Missing transaction");

    // mergedTx will end up with all the signatures; it
    // starts as a clone of the rawtx:
    CMutableTransaction mergedTx(txVariants[0]);

    // Fetch previous transactions (inputs):
    CCoinsView viewDummy;
    CCoinsViewCache view(&viewDummy);
    {
        READLOCK(mempool.cs);
        CCoinsViewCache &viewChain = *pcoinsTip;
        CCoinsViewMemPool viewMempool(&viewChain, mempool);
        view.SetBackend(viewMempool); // temporarily switch cache backend to db+mempool view

        BOOST_FOREACH (const CTxIn &txin, mergedTx.vin)
        {
            view.AccessCoin(txin.prevout); // Load entries from viewChain into view; can fail.
        }

        view.SetBackend(viewDummy); // switch back to avoid locking mempool for too long
    }

    bool fGivenKeys = false;
    CBasicKeyStore tempKeystore;

#ifdef ENABLE_WALLET
    if (pwalletMain)
        EnsureWalletIsUnlocked();
#endif

#ifdef ENABLE_WALLET
    const CKeyStore &keystore = ((fGivenKeys || !pwalletMain) ? tempKeystore : *pwalletMain);
#else
    const CKeyStore &keystore = tempKeystore;
#endif

    int nHashType = SIGHASH_ALL;
    bool pickedForkId = false;
    if (!pickedForkId) // If the user didn't specify, use the configured default for the hash type
    {
        if (IsUAHFforkActiveOnNextBlock(chainActive.Tip()->nHeight))
        {
            nHashType |= SIGHASH_FORKID;
            pickedForkId = true;
        }
    }

    bool fHashSingle = ((nHashType & ~(SIGHASH_ANYONECANPAY | SIGHASH_FORKID)) == SIGHASH_SINGLE);

    // Script verification errors
    UniValue vErrors(UniValue::VARR);

    // Use CTransaction for the constant parts of the
    // transaction to avoid rehashing.
    const CTransaction txConst(mergedTx);
    // Sign what we can:
    for (unsigned int i = 0; i < mergedTx.vin.size(); i++)
    {
        CTxIn &txin = mergedTx.vin[i];
        const Coin &coin = view.AccessCoin(txin.prevout);
        if (coin.IsSpent())
        {
            TxInErrorToJSON(txin, vErrors, "Input not found or already spent");
            continue;
        }
        const CScript &prevPubKey = coin.out.scriptPubKey;
        const CAmount &amount = coin.out.nValue;

        // Only sign SIGHASH_SINGLE if there's a corresponding output:
        if (!fHashSingle || (i < mergedTx.vout.size()))
            SignSignature(keystore, prevPubKey, mergedTx, i, amount, nHashType);

        // ... and merge in other signatures:
        if (pickedForkId)
        {
            BOOST_FOREACH (const CMutableTransaction &txv, txVariants)
            {
                txin.scriptSig = CombineSignatures(prevPubKey,
                    TransactionSignatureChecker(&txConst, i, amount, SCRIPT_ENABLE_SIGHASH_FORKID), txin.scriptSig,
                    txv.vin[i].scriptSig);
            }
            ScriptError serror = SCRIPT_ERR_OK;
            if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS | SCRIPT_ENABLE_SIGHASH_FORKID,
                    MutableTransactionSignatureChecker(&mergedTx, i, amount, SCRIPT_ENABLE_SIGHASH_FORKID), &serror))
            {
                TxInErrorToJSON(txin, vErrors, ScriptErrorString(serror));
            }
        }
        else
        {
            BOOST_FOREACH (const CMutableTransaction &txv, txVariants)
            {
                txin.scriptSig = CombineSignatures(prevPubKey, TransactionSignatureChecker(&txConst, i, amount, 0),
                    txin.scriptSig, txv.vin[i].scriptSig);
            }
            ScriptError serror = SCRIPT_ERR_OK;
            if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS,
                    MutableTransactionSignatureChecker(&mergedTx, i, amount, 0), &serror))
            {
                TxInErrorToJSON(txin, vErrors, ScriptErrorString(serror));
            }
        }
    }

    UniValue result(UniValue::VOBJ);
    if (!vErrors.empty())
    {
        result.push_back(Pair("hex", EncodeHexTx(mergedTx)));
        result.push_back(Pair("errors", vErrors));
    }

    // send tx
    uint256 hashTx = mergedTx.GetHash();

    bool fOverrideFees = true;
    TransactionClass txClass = TransactionClass::DEFAULT;

    CCoinsViewCache &view2 = *pcoinsTip;
    bool fHaveChain = false;
    for (size_t o = 0; !fHaveChain && o < mergedTx.vout.size(); o++)
    {
        const Coin &existingCoin = view2.AccessCoin(COutPoint(hashTx, o));
        fHaveChain = !existingCoin.IsSpent();
    }
    bool fHaveMempool = mempool.exists(hashTx);
    if (!fHaveMempool && !fHaveChain)
    {
        // push to local node and sync with wallets
        CValidationState state;
        bool fMissingInputs;
        if (!AcceptToMemoryPool(mempool, state, mergedTx, false, &fMissingInputs, false, !fOverrideFees, txClass))
        {
            if (state.IsInvalid())
            {
                throw JSONRPCError(
                    RPC_TRANSACTION_REJECTED, strprintf("%i: %s", state.GetRejectCode(), state.GetRejectReason()));
            }
            else
            {
                if (fMissingInputs)
                {
                    throw JSONRPCError(RPC_TRANSACTION_ERROR, "Missing inputs");
                }
                throw JSONRPCError(RPC_TRANSACTION_ERROR, state.GetRejectReason());
            }
        }
#ifdef ENABLE_WALLET
        else
            SyncWithWallets(mergedTx, NULL, -1);
#endif
    }
    else if (fHaveChain)
    {
        throw JSONRPCError(RPC_TRANSACTION_ALREADY_IN_CHAIN, "transaction already in block chain");
    }
    RelayTransaction(mergedTx);

    return hashTx.GetHex();
}

UniValue tokentransfer(const UniValue& params, bool fHelp)
{
    using namespace std;
    if (fHelp || params.size() != 3)
        throw std::runtime_error(
                "tokentransfer \"(feetxid,vout)\" \"(witnesstxid,vout)\" \"(tokenvin,n)\" \"tokenname\" \"address\":\"tokenamount\" \n"

                "\nArguments:\n"
                "1. (feetxid,vout)           \n"
                "2. (witnesstxid,vout)       \n"
                "3. (tokenvin,n)             \n"
                "4. tokenname                \n"
                "5. address:tokenamount      \n"

                "\nResult:\n"
                "\"rawtx\"                 (string) the hex-encoded modified raw transaction\n"

                "\nExamples\n"
                +HelpExampleCli("tokentransfer", "\"[{\\\"txid\\\":\\\"feetxid\\\",\\\"vout\\\":0}]\" \"{\\\"witnesstxid\\\":0 ,\\\"tokenvin\\\":0} \" \"{\\\"name\\\":\\\"token_name\\\" ,\\\"address\\\":1000000}\"")
                +HelpExampleCli("tokentransfer", "\"[{\\\"txid\\\":\\\"feetxid\\\",\\\"vout\\\":0}]\" \"{\\\"witnesstxid\\\":0 ,\\\"tokenvin\\\":0} \" \"{\\\"name\\\":\\\"token_name\\\" ,\\\"address\\\":1000000}\"")
                );

    UniValue inputs = params[0].get_array();
    UniValue witness_utxo = params[1].get_obj();
    UniValue token_sendTo = params[2].get_obj();

    CMutableTransaction rawTx;

    for (unsigned int idx = 0; idx < inputs.size(); idx++)
    {
        const UniValue& input = inputs[idx];
        const UniValue& o = input.get_obj();
        uint256 txid = ParseHashO(o, "txid");

        const UniValue& vout_v = find_value(o, "vout");
        if (!vout_v.isNum())
            throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing vout key");

        int nOutput = vout_v.get_int();
        if (nOutput < 0)
            throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout must be positive");

        uint32_t nSequence = (rawTx.nLockTime ? std::numeric_limits<uint32_t>::max() - 1 : std::numeric_limits<uint32_t>::max());

        // set the sequence number if passed in the parameters object
        const UniValue& sequenceObj = find_value(o, "sequence");
        if (sequenceObj.isNum()) {
            int64_t seqNr64 = sequenceObj.get_int64();
            if (seqNr64 < 0 || seqNr64 > std::numeric_limits<uint32_t>::max())
                throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, sequence number is out of range");
            else
                nSequence = (uint32_t)seqNr64;
        }

        CTxIn in(COutPoint(txid, nOutput), CScript(), nSequence);
        rawTx.vin.push_back(in);
    }

    std::vector<std::string> token_witness_list  = witness_utxo.getKeys();
    std::vector<string> addrList = token_sendTo.getKeys();

    std::string strTokentxid = token_witness_list.at(1);
    std::cout << "strTokentxid: " << strTokentxid <<std::endl;

    std::string strAddress = addrList.at(1);
    std::cout << "strAddress: " << strAddress <<std::endl;

    // std::string strSign = signCommit(strAddress,strTokentxid);
    std::string strSign = "sign";

    std::cout << "strSign: " << strSign <<std::endl;

    CScript script_token_tx;
    script_token_tx << OP_RETURN << TOKEN_TRANSACTION;

    //std::vector<std::string> token_witness_list  = witness_utxo.getKeys();
    for (unsigned int i =0; i<token_witness_list.size(); i++)
    {

        string witness_name = token_witness_list.at(i);

        int vin_pos = witness_utxo[witness_name].get_int();
        if ( !IsTxidUnspent(witness_name,(unsigned int)vin_pos))
        {
            throw JSONRPCError(-8, std::string("witness id  has spent"));
        }
        script_token_tx << ToByteVector(witness_name);
        script_token_tx << vin_pos ;

    }
    script_token_tx << ToByteVector(strSign);

   // std::vector<string> addrList = token_sendTo.getKeys();
    BOOST_FOREACH(const string& name_, addrList)
    {
        if (name_ == "name")
        {
            script_token_tx << ToByteVector(token_sendTo[name_].getValStr());
        }
        else
        {
            CTxDestination destination = DecodeDestination(name_);
            CAmount amount  = token_sendTo[name_].get_int64();
            script_token_tx << amount;
            if (!IsValidDestination(destination))
            {
                throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, std::string("Invalid Bitcoin address: ") + name_);
            }
            script_token_tx << ToByteVector(name_);
        }
    }

    CTxOut out(0, script_token_tx);
    rawTx.vout.push_back(out);
    return EncodeHexTx(rawTx);
}

UniValue listtokeninfo(const UniValue &params, bool fHelp)
{
    if (fHelp || params.size() != 0)
        throw std::runtime_error("listtokeninfo \n");

#ifdef ENABLE_WALLET
    LOCK2(cs_main, pwalletMain ? &pwalletMain->cs_wallet : NULL);
#else
    LOCK(cs_main);
#endif

    int height = chainActive.Height();
    CBlockIndex *pblockindex = NULL;

    std::map<std::string, CAmount> mToken;

    for (int i = 90; i <= height; ++i)
    {
        pblockindex = chainActive[i];
        CBlock block;
        if (ReadBlockFromDisk(block, pblockindex, Params().GetConsensus()))
        {
            for (const auto &tx : block.vtx)
            {
                if (!tx->IsCoinBase())
                {
                    for (const auto &out: tx->vout)
                    {
                        CScript pk = out.scriptPubKey;
                        if (pk[0] == OP_RETURN && pk[1] == OP_10)
                        {
                            // RETURN 10 0x40
                            // 0x66396231366332396464343933313066623065363063393232663062323331343164386536326432373538373435353561643963363666306264653138646336
                            // 1 0x03 0x65736b 0x02 0x1027 0x14 0xd5a0da39ece93072133fc42e4858974586ece592

                            TokenStruct ts = VerifyTokenScript(pk);

                            // check (txid,vout)
                            if (!IsTxidUnspent(ts.txid, (const uint32_t)(ts.vout)))
                                continue;

                            // check address
                            CTxDestination dest = DecodeDestination(ts.address);
                            isminetype mine = pwalletMain ? IsMine(*pwalletMain, dest, chainActive.Tip()) : ISMINE_NO;
                            if (!mine)
                                continue;

                            mToken[ts.name] += ts.amount;
                        }
                        else if (pk[0] == OP_RETURN && pk[1] == OP_11)
                        {
                            TokenStruct ts = VerifyTokenScript(pk);

                            if (!IsTxidUnspent(ts.txid, (const uint32_t)(ts.vout)))
                                continue;

                            CTxDestination dest = DecodeDestination(ts.address);
                            isminetype mine = pwalletMain ? IsMine(*pwalletMain, dest, chainActive.Tip()) : ISMINE_NO;
                            if (!mine)
                                continue;

                            // if (!ts.sign_ok)
                            //     continue;

                            mToken[ts.name] += ts.amount;
                        }
                    }
                }
            }
        }
    }

    UniValue result(UniValue::VARR);
    for ( auto &it: mToken )
    {
        UniValue obj(UniValue::VOBJ);
        obj.push_back(Pair("token", it.first));
        obj.push_back(Pair("amount", it.second));
        result.push_back(obj);
    }
    return result;
}
static  void GetTokenSignScript(const std::vector<std::string>& token_input_addresses,const std::string& message,CScript&sign_script )
{
   sign_script << token_input_addresses.size();
   for ( unsigned int i =0; i < token_input_addresses.size(); i++ )
   {
       std::string sign_message ;

       CTxDestination dest = DecodeDestination(token_input_addresses.at(i));
       if (!IsValidDestination(dest))
           throw JSONRPCError(RPC_TYPE_ERROR, "Invalid address");

       const CKeyID *keyID = boost::get<CKeyID>(&dest);
       if (!keyID)
           throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key");

       CKey key;
       if (!pwalletMain->GetKey(*keyID, key))
           throw JSONRPCError(RPC_WALLET_ERROR, "Private key not available");
       sign_message = signCommit(key,message);
       sign_script << ToByteVector(sign_message);
   }

}

UniValue minttoken(const UniValue& params, bool fHelp)
{
    if (fHelp || params.size() != 3)
        throw std::runtime_error(
                "minttoken \"(feetxid,vout)\" \"(witnesstxid,vout)\" {\"tokenname\" \"tokenamount\" \"address\"}\n"

                "\nArguments:\n"
                "1. (feetxid,vout)                                \n"
                "2. (witnesstxid,vout)                            \n"
                "3. {\"tokenname\" \"tokenamount\" \"address\"}   \n"

                "\nResult:\n"
                "\"txid\"                 (string) the hash of mint w transaction\n"

                "\nExamples\n"
                +HelpExampleCli("minttoken", "\"[{\\\"txid\\\":\\\"feetxid\\\",\\\"vout\\\":0}]\" \"{\\\"witnesstxid\\\":0}\" \"{\\\"name\\\":\\\"token_name\\\" ,\\\"amount\\\":10000,\\\"address\\\":\\\"xxxxxx\\\"}\"")
                +HelpExampleCli("minttoken", "\"[{\\\"txid\\\":\\\"feetxid\\\",\\\"vout\\\":0}]\" \"{\\\"witnesstxid\\\":0}\" \"{\\\"name\\\":\\\"token_name\\\" ,\\\"amount\\\":10000,\\\"address\\\":\\\"xxxxxx\\\"}\"")
                );

    UniValue inputs = params[0].get_array();
    UniValue token_output = params[1].get_obj();

    CMutableTransaction rawTx;

    for (unsigned int idx = 0; idx < inputs.size(); idx++)
    {
        const UniValue& input = inputs[idx];
        const UniValue& o = input.get_obj();
        uint256 txid = ParseHashO(o, "txid");

        const UniValue& vout_v = find_value(o, "vout");
        if (!vout_v.isNum())
            throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing vout key");

        int nOutput = vout_v.get_int();
        if (nOutput < 0)
            throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout must be positive");

        uint32_t nSequence = (rawTx.nLockTime ? std::numeric_limits<uint32_t>::max() - 1 : std::numeric_limits<uint32_t>::max());

        // set the sequence number if passed in the parameters object
        const UniValue& sequenceObj = find_value(o, "sequence");
        if (sequenceObj.isNum()) {
            int64_t seqNr64 = sequenceObj.get_int64();
            if (seqNr64 < 0 || seqNr64 > std::numeric_limits<uint32_t>::max())
                throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, sequence number is out of range");
            else
                nSequence = (uint32_t)seqNr64;
        }

        CTxIn in(COutPoint(txid, nOutput), CScript(), nSequence);
        rawTx.vin.push_back(in);
    }

    CScript script_token_tx;
    unsigned int flag_size = 1;
    script_token_tx << OP_RETURN << flag_size << TOKEN_ISSUE;

    unsigned int output_size = 0;
    std::vector<std::string> addrList = token_output.getKeys();
    output_size = addrList.size();

    if (output_size != 3)
        throw JSONRPCError(TOKENFORMATERROR, "mint token output size error");
    script_token_tx << flag_size ;

    BOOST_FOREACH(const std::string& name_, addrList)
    {
        if (name_ == "name")
        {
            script_token_tx << ToByteVector(token_output[name_].getValStr());
        }
        else if (name_ == "amount")
        {
            CAmount amount  = token_output[name_].get_int64();
            script_token_tx << amount;
        }
        else if (name_ == "address")
        {
            std::string addr = token_output[name_].getValStr();
            CTxDestination destination = DecodeDestination(addr);
            if (!IsValidDestination(destination))
            {
                throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, std::string("Invalid Bitcoin address: ") + addr);
            }
            script_token_tx << ToByteVector(addr);
        }
    }

    CTxOut out(0, script_token_tx);
    rawTx.vout.push_back(out);
    return EncodeHexTx(rawTx);
}

UniValue transfertoken(const UniValue& params, bool fHelp)
{
    using namespace std;
    if (fHelp || params.size() != 3)
        throw std::runtime_error(
                "transfertoken \"(feetxid,vout)\" \"(witnesstxid,vout)\" \"(tokenvin,n)\" \"tokenname\" \"address\":\"tokenamount\" \n"

                "\nArguments:\n"
                "1. (feetxid,vout)           \n"
                "2. (witnesstxid,vout)       \n"
                "3. (tokenvin,n)             \n"
                "4. tokenname                \n"
                "5. address:tokenamount      \n"

                "\nResult:\n"
                "\"rawtx\"                 (string) the hex-encoded modified raw transaction\n"

                "\nExamples\n"
                +HelpExampleCli("transfertoken", "\"[{\\\"txid\\\":\\\"feetxid\\\",\\\"vout\\\":0}]\" \"{\\\"witnesstxid\\\":0 ,\\\"tokenvin\\\":0} \" \"{\\\"name\\\":\\\"token_name\\\" ,\\\"address\\\":1000000}\"")
                +HelpExampleCli("transfertoken", "\"[{\\\"txid\\\":\\\"feetxid\\\",\\\"vout\\\":0}]\" \"{\\\"witnesstxid\\\":0 ,\\\"tokenvin\\\":0} \" \"{\\\"name\\\":\\\"token_name\\\" ,\\\"address\\\":1000000}\"")
                );

    UniValue inputs = params[0].get_array();
    UniValue token_inputs = params[1].get_array();
    UniValue token_outputs = params[2].get_array();

    CMutableTransaction rawTx;

    for (unsigned int idx = 0; idx < inputs.size(); idx++)
    {
        const UniValue& input = inputs[idx];
        const UniValue& o = input.get_obj();
        uint256 txid = ParseHashO(o, "txid");

        const UniValue& vout_v = find_value(o, "vout");
        if (!vout_v.isNum())
            throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing vout key");

        int nOutput = vout_v.get_int();
        if (nOutput < 0)
            throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout must be positive");

        uint32_t nSequence = (rawTx.nLockTime ? std::numeric_limits<uint32_t>::max() - 1 : std::numeric_limits<uint32_t>::max());

        // set the sequence number if passed in the parameters object
        const UniValue& sequenceObj = find_value(o, "sequence");
        if (sequenceObj.isNum()) {
            int64_t seqNr64 = sequenceObj.get_int64();
            if (seqNr64 < 0 || seqNr64 > std::numeric_limits<uint32_t>::max())
                throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, sequence number is out of range");
            else
                nSequence = (uint32_t)seqNr64;
        }

        CTxIn in(COutPoint(txid, nOutput), CScript(), nSequence);
        rawTx.vin.push_back(in);
    }

    unsigned int witness_size = token_inputs.size();
    unsigned int inputs_size = witness_size*2;
    std::string token_name = "";
    CScript script_input;

    std::vector<std::string> sign_address;
    script_input << inputs_size;
    uint64_t token_input_amount = 0;
    for (unsigned int idx = 0; idx < token_inputs.size() ; idx++)
    {
        const UniValue& input = token_inputs[idx];
        const UniValue& o = input.get_obj();
        uint256 token_txid = ParseHashO(o, "txid");

        const UniValue& token_vout_v = find_value(o, "vout");
        if (!token_vout_v.isNum())
            throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing vout key");

        int n_token_output = token_vout_v.get_int();
        if ( n_token_output < 0 )
            throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout must be positive");

        if ( !TokenInputValid(token_txid.ToString(),n_token_output) )
            throw JSONRPCError(TOKENINPUTSIZEERROR, "Token input txid or vout is invalid!");

        std::string token_name_txid;
        uint64_t token_amount_txid = 0;
        if (!ContractTally::Instance()->GetTokenNameAmount(token_txid.ToString(),n_token_output,token_name_txid,token_amount_txid))
            throw JSONRPCError(TOKENINPUTSIZEERROR, "Invalid token vin ");

        if ( token_name.empty() || token_name == "" )
        {
            token_name = token_name_txid;
        }
        else if ( token_name != token_name_txid)
        {
            throw JSONRPCError(TOKENINPUTSIZEERROR, "Invalid token name ,have different token name ");
        }

        token_input_amount += token_amount_txid;

        script_input << ToByteVector(token_txid.ToString()) << n_token_output;
        sign_address.push_back(token_txid.ToString());
    }

    unsigned int output_size = token_inputs.size()*4;
    CScript script_output;
    script_output << output_size;
    std::string sign_message;
    uint64_t token_output_amount = 0 ;
    for ( unsigned int idx = 0; idx < token_outputs.size() ; idx++ )
    {
        const UniValue& output = token_outputs[idx];
        const UniValue& o = output.get_obj();

        //uint256 token_txid  = ParseHashO(o,"address");
        const UniValue&token_address_v = find_value(o,"address");
        if ( !token_address_v.isNum() )
            throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing address key");
        std::string str_token_address = token_address_v.get_str();

        const UniValue& token_vout_v = find_value(o,"vout");
        if ( !token_vout_v.isNum() )
            throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing vout key");
        int n_token_vout = token_vout_v.get_int();

        const UniValue& token_name_v = find_value(o,"name");
        if ( !token_name_v.isStr() )
            throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing name key");
        std::string str_token_name = token_name_v.get_str();

        if ( token_name  != str_token_name )
            throw JSONRPCError(TOKENOUTPUTSIZEERROR, "Invalid parameter, vin token name diff from vout token name");

        const UniValue& token_amount_v = find_value(o,"amount");
        if ( !token_amount_v.isNum() )
            throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing amount key");
        uint64_t amount = token_amount_v.get_int64();
        token_output_amount += amount;
        sign_message += str_token_address;
        sign_message += contractio::intToString(n_token_vout);
        sign_message += str_token_name;
        sign_message += contractio::uint64ToString(amount);
        script_output << ToByteVector(str_token_address);
        script_output << n_token_vout ;
        script_output << ToByteVector(str_token_name);
        script_output << amount;
    }

    if (token_input_amount < token_output_amount)
        throw JSONRPCError(TOKENSTATISTICS, "Invalid token inputs, less than outputs");

    CScript script_sign;
    GetTokenSignScript(sign_address,sign_message,script_sign);

    CScript  script_token_tx;
    unsigned int flag_size = 1;
    script_token_tx << OP_RETURN << flag_size;
    script_token_tx << flag_size << TOKEN_TRANSACTION;
    script_token_tx += script_sign;
    script_token_tx += script_input;
    script_token_tx += script_output;
    CTxOut out(0, script_token_tx);
    rawTx.vout.push_back(out);
    return EncodeHexTx(rawTx);
}

static const CRPCCommand commands[] =
{ //  category                             name                            actor (function)               okSafeMode
  //  ------------------------------------ ------------------------------- ------------------------------ ----------
#ifdef ENABLE_WALLET
    { "constract token", "tokenmint",                                    &tokenmint,               false },
    { "constract token", "tokentransfer",                               &tokentransfer,                    false },
    { "constract token", "listtokeninfo",                               &listtokeninfo,                    false },
    { "constract token", "minttoken",                                    &minttoken,               false },
    { "constract token", "transfertoken",                               &transfertoken,                    false },
#endif
};

void RegisterContractTokenCommands(CRPCTable &tableRPC)
{
    for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
        tableRPC.appendCommand(commands[vcidx].name, &commands[vcidx]);
}

max_stars_repo_name: fourseaLee/bch

max_issues_repo_name: fourseaLee/bch

max_forks_repo_name: fourseaLee/bch


text:
// Copyright 2015-2020 Tier IV, Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef OPENSCENARIO_INTERPRETER__SYNTAX__INTEGER_HPP_
#define OPENSCENARIO_INTERPRETER__SYNTAX__INTEGER_HPP_

#include <boost/lexical_cast.hpp>
#include <openscenario_interpreter/error.hpp>
#include <std_msgs/msg/int64.hpp>
#include <string>

namespace openscenario_interpreter
{
inline namespace syntax
{
struct Integer : public std_msgs::msg::Int64
{
  using value_type = decltype(std_msgs::msg::Int64::data);

  explicit Integer() = default;

  explicit Integer(value_type value) { data = value; }

  explicit Integer(const std::string & s)
  try {
    data = boost::lexical_cast<value_type>(s);
  } catch (const boost::bad_lexical_cast &) {
    throw INVALID_NUMERIC_LITERAL_SPECIFIED(s);
  }

  constexpr operator value_type() const noexcept { return data; }

  auto & operator+=(const double & rhs)
  {
    data += rhs;
    return *this;
  }

  auto & operator*=(const double & rhs)
  {
    data *= rhs;
    return *this;
  }
};

static_assert(std::is_standard_layout<Integer>::value, "");

static_assert(not std::is_trivial<Integer>::value, "");

std::istream & operator>>(std::istream &, Integer &);

std::ostream & operator<<(std::ostream &, const Integer &);
}  // namespace syntax
}  // namespace openscenario_interpreter

#endif  // OPENSCENARIO_INTERPRETER__SYNTAX__INTEGER_HPP_