text:
/**
 * Copyright Soramitsu Co., Ltd. 2017 All Rights Reserved.
 * http://soramitsu.co.jp
 *
 * 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.
 */

#include <boost/range/join.hpp>
#include "builders/protobuf/proposal.hpp"
#include "builders/protobuf/transaction.hpp"
#include "framework/test_subscriber.hpp"
#include "module/irohad/network/network_mocks.hpp"
#include "module/shared_model/builders/protobuf/test_block_builder.hpp"
#include "module/shared_model/builders/protobuf/test_proposal_builder.hpp"
#include "module/shared_model/builders/protobuf/test_transaction_builder.hpp"
#include "torii/processor/transaction_processor_impl.hpp"

using namespace iroha;
using namespace iroha::network;
using namespace iroha::torii;
using namespace framework::test_subscriber;

using ::testing::_;
using ::testing::Return;

class TransactionProcessorTest : public ::testing::Test {
 public:
  void SetUp() override {
    pcs = std::make_shared<MockPeerCommunicationService>();

    EXPECT_CALL(*pcs, on_proposal())
        .WillRepeatedly(Return(prop_notifier.get_observable()));

    EXPECT_CALL(*pcs, on_commit())
        .WillRepeatedly(Return(commit_notifier.get_observable()));

    tp = std::make_shared<TransactionProcessorImpl>(pcs);
  }

 protected:
  using StatusMapType = std::unordered_map<
      shared_model::crypto::Hash,
      std::shared_ptr<shared_model::interface::TransactionResponse>,
      shared_model::crypto::Hash::Hasher>;

  /**
   * Checks if all transactions have corresponding status
   * @param transactions transactions to check status
   * @param status to be checked
   */
  template <typename Status>
  void validateStatuses(
      std::vector<shared_model::proto::Transaction> &transactions) {
    for (const auto &tx : transactions) {
      auto tx_status = status_map.find(tx.hash());
      ASSERT_NE(tx_status, status_map.end());
      boost::apply_visitor(
          [](auto val) {
            if (std::is_same<decltype(val), Status>::value) {
              SUCCEED();
            } else {
              FAIL() << "obtained: " << typeid(decltype(val)).name()
                     << ", expected: " << typeid(Status).name() << std::endl;
            }
          },
          tx_status->second->get());
    }
  }

  std::shared_ptr<MockPeerCommunicationService> pcs;
  std::shared_ptr<TransactionProcessorImpl> tp;

  StatusMapType status_map;
  shared_model::builder::TransactionStatusBuilder<
      shared_model::proto::TransactionStatusBuilder>
      status_builder;

  rxcpp::subjects::subject<std::shared_ptr<shared_model::interface::Proposal>>
      prop_notifier;
  rxcpp::subjects::subject<Commit> commit_notifier;

  const size_t proposal_size = 5;
  const size_t block_size = 3;
};

/**
 * @given transaction processor
 * @when transactions passed to processor compose proposal which is sent to peer
 * communication service
 * @then for every transaction STATELESS_VALID status is returned
 */
TEST_F(TransactionProcessorTest, TransactionProcessorOnProposalTest) {
  std::vector<shared_model::proto::Transaction> txs;
  for (size_t i = 0; i < proposal_size; i++) {
    auto &&tx = shared_model::proto::TransactionBuilder()
                    .txCounter(i + 1)
                    .createdTime(iroha::time::now())
                    .creatorAccountId("admin@ru")
                    .addAssetQuantity("admin@tu", "coin#coin", "1.0")
                    .build()
                    .signAndAddSignature(
                        shared_model::crypto::DefaultCryptoAlgorithmType::
                            generateKeypair());
    txs.push_back(tx);
    status_map[tx.hash()] =
        status_builder.notReceived().txHash(tx.hash()).build();
  }

  auto wrapper =
      make_test_subscriber<CallExact>(tp->transactionNotifier(), proposal_size);
  wrapper.subscribe([this](auto response) {
    status_map[response->transactionHash()] = response;
  });

  EXPECT_CALL(*pcs, propagate_transaction(_)).Times(txs.size());

  for (const auto &tx : txs) {
    tp->transactionHandle(
        std::shared_ptr<shared_model::interface::Transaction>(clone(tx)));
  }

  // create proposal and notify about it
  auto proposal = std::make_shared<shared_model::proto::Proposal>(
      shared_model::proto::ProposalBuilder()
          .height(2)
          .createdTime(iroha::time::now())
          .transactions(txs)
          .build());

  prop_notifier.get_subscriber().on_next(proposal);
  prop_notifier.get_subscriber().on_completed();

  ASSERT_TRUE(wrapper.validate());

  SCOPED_TRACE("Stateless valid status verification");
  validateStatuses<shared_model::detail::PolymorphicWrapper<
      shared_model::interface::StatelessValidTxResponse>>(txs);
}

/**
 * @given transaction processor
 * @when transactions compose proposal which is sent to peer
 * communication service @and all transactions composed the block
 * @then for every transaction STATEFUL_VALID status is returned
 */
TEST_F(TransactionProcessorTest, TransactionProcessorBlockCreatedTest) {
  std::vector<shared_model::proto::Transaction> txs;
  for (size_t i = 0; i < proposal_size; i++) {
    auto &&tx = shared_model::proto::TransactionBuilder()
                    .txCounter(i + 1)
                    .createdTime(iroha::time::now())
                    .creatorAccountId("admin@ru")
                    .addAssetQuantity("admin@tu", "coin#coin", "1.0")
                    .build()
                    .signAndAddSignature(
                        shared_model::crypto::DefaultCryptoAlgorithmType::
                            generateKeypair());
    txs.push_back(tx);
    status_map[tx.hash()] =
        status_builder.notReceived().txHash(tx.hash()).build();
  }

  auto wrapper = make_test_subscriber<CallExact>(
      tp->transactionNotifier(),
      txs.size() * 2);  // every transaction is notified that it is stateless
                        // valid and  then stateful valid
  wrapper.subscribe([this](auto response) {
    status_map[response->transactionHash()] = response;
  });

  EXPECT_CALL(*pcs, propagate_transaction(_)).Times(txs.size());

  for (const auto &tx : txs) {
    tp->transactionHandle(
        std::shared_ptr<shared_model::interface::Transaction>(clone(tx)));
  }

  // 1. Create proposal and notify transaction processor about it
  auto proposal = std::make_shared<shared_model::proto::Proposal>(
      shared_model::proto::ProposalBuilder()
          .height(2)
          .createdTime(iroha::time::now())
          .transactions(txs)
          .build());

  prop_notifier.get_subscriber().on_next(proposal);
  prop_notifier.get_subscriber().on_completed();

  auto block = TestBlockBuilder()
                   .height(1)
                   .createdTime(iroha::time::now())
                   .transactions(txs)
                   .prevHash(shared_model::crypto::Hash(std::string(32, '0')))
                   .build();

  // 2. Create block and notify transaction processor about it
  rxcpp::subjects::subject<std::shared_ptr<shared_model::interface::Block>>
      blocks_notifier;

  commit_notifier.get_subscriber().on_next(blocks_notifier.get_observable());

  blocks_notifier.get_subscriber().on_next(
      std::shared_ptr<shared_model::interface::Block>(clone(block)));
  // Note blocks_notifier hasn't invoked on_completed, so
  // transactions are not commited

  ASSERT_TRUE(wrapper.validate());

  SCOPED_TRACE("Stateful valid status verification");
  validateStatuses<shared_model::detail::PolymorphicWrapper<
      shared_model::interface::StatefulValidTxResponse>>(txs);
}

/**
 * @given transaction processor
 * @when transactions compose proposal which is sent to peer
 * communication service @and all transactions composed the block @and were
 * committed
 * @then for every transaction COMMIT status is returned
 */
TEST_F(TransactionProcessorTest, TransactionProcessorOnCommitTest) {
  std::vector<shared_model::proto::Transaction> txs;
  for (size_t i = 0; i < proposal_size; i++) {
    auto &&tx = shared_model::proto::TransactionBuilder()
                    .txCounter(i + 1)
                    .createdTime(iroha::time::now())
                    .creatorAccountId("admin@ru")
                    .addAssetQuantity("admin@tu", "coin#coin", "1.0")
                    .build()
                    .signAndAddSignature(
                        shared_model::crypto::DefaultCryptoAlgorithmType::
                            generateKeypair());
    txs.push_back(tx);
    status_map[tx.hash()] =
        status_builder.notReceived().txHash(tx.hash()).build();
  }

  auto wrapper = make_test_subscriber<CallExact>(
      tp->transactionNotifier(),
      txs.size() * 3);  // evey transaction is notified that it is first
                        // stateless valid, then stateful valid and
                        // eventually committed
  wrapper.subscribe([this](auto response) {
    status_map[response->transactionHash()] = response;
  });

  EXPECT_CALL(*pcs, propagate_transaction(_)).Times(txs.size());

  for (const auto &tx : txs) {
    tp->transactionHandle(
        std::shared_ptr<shared_model::interface::Transaction>(clone(tx)));
  }

  // 1. Create proposal and notify transaction processor about it
  auto proposal = std::make_shared<shared_model::proto::Proposal>(
      shared_model::proto::ProposalBuilder()
          .height(2)
          .createdTime(iroha::time::now())
          .transactions(txs)
          .build());

  prop_notifier.get_subscriber().on_next(proposal);
  prop_notifier.get_subscriber().on_completed();

  auto block = TestBlockBuilder()
                   .height(1)
                   .createdTime(iroha::time::now())
                   .transactions(txs)
                   .prevHash(shared_model::crypto::Hash(std::string(32, '0')))
                   .build();

  // 2. Create block and notify transaction processor about it
  Commit single_commit = rxcpp::observable<>::just(
      std::shared_ptr<shared_model::interface::Block>(clone(block)));
  commit_notifier.get_subscriber().on_next(single_commit);

  ASSERT_TRUE(wrapper.validate());

  SCOPED_TRACE("Committed status verification");
  validateStatuses<shared_model::detail::PolymorphicWrapper<
      shared_model::interface::CommittedTxResponse>>(txs);
}

/**
 * @given transaction processor
 * @when transactions compose proposal which is sent to peer
 * communication service @and some transactions became part of block, while some
 * were not committed
 * @then for every transaction from block COMMIT status is returned @and for
 * every transaction not from block STATEFUL_INVALID_STATUS was returned
 */
TEST_F(TransactionProcessorTest, TransactionProcessorInvalidTxsTest) {
  std::vector<shared_model::proto::Transaction> block_txs;
  for (size_t i = 0; i < block_size; i++) {
    auto &&tx = shared_model::proto::TransactionBuilder()
                    .txCounter(i + 1)
                    .createdTime(iroha::time::now())
                    .creatorAccountId("admin@ru")
                    .addAssetQuantity("admin@tu", "coin#coin", "1.0")
                    .build()
                    .signAndAddSignature(
                        shared_model::crypto::DefaultCryptoAlgorithmType::
                            generateKeypair());
    block_txs.push_back(tx);
    status_map[tx.hash()] =
        status_builder.notReceived().txHash(tx.hash()).build();
  }

  std::vector<shared_model::proto::Transaction>
      invalid_txs;  // transactions will be stateful invalid if appeared
                    // in proposal but didn't appear in block
  for (size_t i = block_size; i < proposal_size; i++) {
    auto &&tx = shared_model::proto::TransactionBuilder()
                    .txCounter(i + 1)
                    .createdTime(iroha::time::now())
                    .creatorAccountId("admin@ru")
                    .addAssetQuantity("admin@tu", "coin#coin", "1.0")
                    .build()
                    .signAndAddSignature(
                        shared_model::crypto::DefaultCryptoAlgorithmType::
                            generateKeypair());
    invalid_txs.push_back(tx);
    status_map[tx.hash()] =
        status_builder.notReceived().txHash(tx.hash()).build();
  }

  auto wrapper = make_test_subscriber<CallExact>(
      tp->transactionNotifier(),
      proposal_size * 2
          + block_size);  // For all transactions from proposal
                          // transaction notifier will notified
                          // twice (first that they are stateless
                          // valid and second that they either
                          // passed or not stateful validation)
                          // Plus all transactions from block will
                          // be committed and corresponding status will be sent

  wrapper.subscribe([this](auto response) {
    status_map[response->transactionHash()] = response;
  });

  auto proposal = std::make_shared<shared_model::proto::Proposal>(
      shared_model::proto::ProposalBuilder()
          .height(2)
          .createdTime(iroha::time::now())
          .transactions(boost::join(block_txs, invalid_txs))
          .build());

  prop_notifier.get_subscriber().on_next(proposal);
  prop_notifier.get_subscriber().on_completed();

  auto block = TestBlockBuilder()
                   .height(1)
                   .createdTime(iroha::time::now())
                   .transactions(block_txs)
                   .prevHash(shared_model::crypto::Hash(std::string(32, '0')))
                   .build();

  Commit single_commit = rxcpp::observable<>::just(
      std::shared_ptr<shared_model::interface::Block>(clone(block)));
  commit_notifier.get_subscriber().on_next(single_commit);
  ASSERT_TRUE(wrapper.validate());

  {
    SCOPED_TRACE("Stateful invalid status verification");
    // check that all invalid transactions will have stateful invalid status
    validateStatuses<shared_model::detail::PolymorphicWrapper<
        shared_model::interface::StatefulFailedTxResponse>>(invalid_txs);
  }
  {
    SCOPED_TRACE("Committed status verification");
    // check that all transactions from block will be committed
    validateStatuses<shared_model::detail::PolymorphicWrapper<
        shared_model::interface::CommittedTxResponse>>(block_txs);
  }
}

max_stars_repo_name: steephengeorge/iroha

max_issues_repo_name: steephengeorge/iroha

max_forks_repo_name: steephengeorge/iroha


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

/* Author: Mrinal Kalakrishnan, Ken Anderson */

#include <moveit/distance_field/propagation_distance_field.h>
#include <visualization_msgs/msg/marker.h>
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/copy.hpp>
#include <boost/iostreams/filter/zlib.hpp>
#include "rclcpp/rclcpp.hpp"

namespace distance_field
{
// Logger
static const rclcpp::Logger LOGGER = rclcpp::get_logger("moveit_distance_field.propagation_distance_field");

PropagationDistanceField::PropagationDistanceField(double size_x, double size_y, double size_z, double resolution,
                                                   double origin_x, double origin_y, double origin_z,
                                                   double max_distance, bool propagate_negative)
  : DistanceField(size_x, size_y, size_z, resolution, origin_x, origin_y, origin_z)
  , propagate_negative_(propagate_negative)
  , max_distance_(max_distance)
{
  initialize();
}

PropagationDistanceField::PropagationDistanceField(const octomap::OcTree& octree, const octomap::point3d& bbx_min,
                                                   const octomap::point3d& bbx_max, double max_distance,
                                                   bool propagate_negative_distances)
  : DistanceField(bbx_max.x() - bbx_min.x(), bbx_max.y() - bbx_min.y(), bbx_max.z() - bbx_min.z(),
                  octree.getResolution(), bbx_min.x(), bbx_min.y(), bbx_min.z())
  , propagate_negative_(propagate_negative_distances)
  , max_distance_(max_distance)
  , max_distance_sq_(0)  // avoid gcc warning about uninitialized value
{
  initialize();
  addOcTreeToField(&octree);
}

PropagationDistanceField::PropagationDistanceField(std::istream& is, double max_distance,
                                                   bool propagate_negative_distances)
  : DistanceField(0, 0, 0, 0, 0, 0, 0), propagate_negative_(propagate_negative_distances), max_distance_(max_distance)
{
  readFromStream(is);
}

void PropagationDistanceField::initialize()
{
  max_distance_sq_ = ceil(max_distance_ / resolution_) * ceil(max_distance_ / resolution_);
  voxel_grid_ =
      std::make_shared<VoxelGrid<PropDistanceFieldVoxel>>(size_x_, size_y_, size_z_, resolution_, origin_x_, origin_y_,
                                                          origin_z_, PropDistanceFieldVoxel(max_distance_sq_, 0));

  initNeighborhoods();

  bucket_queue_.resize(max_distance_sq_ + 1);
  negative_bucket_queue_.resize(max_distance_sq_ + 1);

  // create a sqrt table:
  sqrt_table_.resize(max_distance_sq_ + 1);
  for (int i = 0; i <= max_distance_sq_; ++i)
    sqrt_table_[i] = sqrt(double(i)) * resolution_;

  reset();
}

void PropagationDistanceField::print(const VoxelSet& set)
{
  RCLCPP_DEBUG(LOGGER, "[");
  VoxelSet::const_iterator it;
  for (it = set.begin(); it != set.end(); ++it)
  {
    Eigen::Vector3i loc1 = *it;
    RCLCPP_DEBUG(LOGGER, "%d, %d, %d ", loc1.x(), loc1.y(), loc1.z());
  }
  RCLCPP_DEBUG(LOGGER, "] size=%u\n", (unsigned int)set.size());
}

void PropagationDistanceField::print(const EigenSTL::vector_Vector3d& points)
{
  RCLCPP_DEBUG(LOGGER, "[");
  EigenSTL::vector_Vector3d::const_iterator it;
  for (it = points.begin(); it != points.end(); ++it)
  {
    Eigen::Vector3d loc1 = *it;
    RCLCPP_DEBUG(LOGGER, "%g, %g, %g ", loc1.x(), loc1.y(), loc1.z());
  }
  RCLCPP_DEBUG(LOGGER, "] size=%u\n", (unsigned int)points.size());
}

void PropagationDistanceField::updatePointsInField(const EigenSTL::vector_Vector3d& old_points,
                                                   const EigenSTL::vector_Vector3d& new_points)
{
  VoxelSet old_point_set;
  for (const Eigen::Vector3d& old_point : old_points)
  {
    Eigen::Vector3i voxel_loc;
    bool valid = worldToGrid(old_point.x(), old_point.y(), old_point.z(), voxel_loc.x(), voxel_loc.y(), voxel_loc.z());
    if (valid)
    {
      old_point_set.insert(voxel_loc);
    }
  }

  VoxelSet new_point_set;
  for (const Eigen::Vector3d& new_point : new_points)
  {
    Eigen::Vector3i voxel_loc;
    bool valid = worldToGrid(new_point.x(), new_point.y(), new_point.z(), voxel_loc.x(), voxel_loc.y(), voxel_loc.z());
    if (valid)
    {
      new_point_set.insert(voxel_loc);
    }
  }
  CompareEigenVector3i comp;

  EigenSTL::vector_Vector3i old_not_new;
  std::set_difference(old_point_set.begin(), old_point_set.end(), new_point_set.begin(), new_point_set.end(),
                      std::inserter(old_not_new, old_not_new.end()), comp);

  EigenSTL::vector_Vector3i new_not_old;
  std::set_difference(new_point_set.begin(), new_point_set.end(), old_point_set.begin(), old_point_set.end(),
                      std::inserter(new_not_old, new_not_old.end()), comp);

  EigenSTL::vector_Vector3i new_not_in_current;
  for (Eigen::Vector3i& voxel_loc : new_not_old)
  {
    if (voxel_grid_->getCell(voxel_loc.x(), voxel_loc.y(), voxel_loc.z()).distance_square_ != 0)
    {
      new_not_in_current.push_back(voxel_loc);
    }
  }

  removeObstacleVoxels(old_not_new);
  addNewObstacleVoxels(new_not_in_current);
}

void PropagationDistanceField::addPointsToField(const EigenSTL::vector_Vector3d& points)
{
  EigenSTL::vector_Vector3i voxel_points;

  for (const Eigen::Vector3d& point : points)
  {
    // Convert to voxel coordinates
    Eigen::Vector3i voxel_loc;
    bool valid = worldToGrid(point.x(), point.y(), point.z(), voxel_loc.x(), voxel_loc.y(), voxel_loc.z());

    if (valid)
    {
      if (voxel_grid_->getCell(voxel_loc.x(), voxel_loc.y(), voxel_loc.z()).distance_square_ > 0)
      {
        voxel_points.push_back(voxel_loc);
      }
    }
  }
  addNewObstacleVoxels(voxel_points);
}

void PropagationDistanceField::removePointsFromField(const EigenSTL::vector_Vector3d& points)
{
  EigenSTL::vector_Vector3i voxel_points;
  // VoxelSet voxel_locs;

  for (const Eigen::Vector3d& point : points)
  {
    // Convert to voxel coordinates
    Eigen::Vector3i voxel_loc;
    bool valid = worldToGrid(point.x(), point.y(), point.z(), voxel_loc.x(), voxel_loc.y(), voxel_loc.z());

    if (valid)
    {
      voxel_points.push_back(voxel_loc);
      // if(voxel_grid_->getCell(voxel_loc.x(),voxel_loc.y(),voxel_loc.z()).distance_square_ == 0) {
      //  voxel_locs.insert(voxel_loc);
      //}
    }
  }

  removeObstacleVoxels(voxel_points);
}

void PropagationDistanceField::addNewObstacleVoxels(const EigenSTL::vector_Vector3i& voxel_points)
{
  int initial_update_direction = getDirectionNumber(0, 0, 0);
  bucket_queue_[0].reserve(voxel_points.size());
  EigenSTL::vector_Vector3i negative_stack;
  if (propagate_negative_)
  {
    negative_stack.reserve(getXNumCells() * getYNumCells() * getZNumCells());
    negative_bucket_queue_[0].reserve(voxel_points.size());
  }

  for (const Eigen::Vector3i& voxel_point : voxel_points)
  {
    PropDistanceFieldVoxel& voxel = voxel_grid_->getCell(voxel_point.x(), voxel_point.y(), voxel_point.z());
    const Eigen::Vector3i& loc = voxel_point;
    voxel.distance_square_ = 0;
    voxel.closest_point_ = loc;
    voxel.update_direction_ = initial_update_direction;
    bucket_queue_[0].push_back(loc);
    if (propagate_negative_)
    {
      voxel.negative_distance_square_ = max_distance_sq_;
      voxel.closest_negative_point_.x() = PropDistanceFieldVoxel::UNINITIALIZED;
      voxel.closest_negative_point_.y() = PropDistanceFieldVoxel::UNINITIALIZED;
      voxel.closest_negative_point_.z() = PropDistanceFieldVoxel::UNINITIALIZED;
      negative_stack.push_back(loc);
    }
  }
  propagatePositive();

  if (propagate_negative_)
  {
    while (!negative_stack.empty())
    {
      Eigen::Vector3i loc = negative_stack.back();
      negative_stack.pop_back();

      for (int neighbor = 0; neighbor < 27; ++neighbor)
      {
        Eigen::Vector3i diff = getLocationDifference(neighbor);
        Eigen::Vector3i nloc(loc.x() + diff.x(), loc.y() + diff.y(), loc.z() + diff.z());

        if (isCellValid(nloc.x(), nloc.y(), nloc.z()))
        {
          PropDistanceFieldVoxel& nvoxel = voxel_grid_->getCell(nloc.x(), nloc.y(), nloc.z());
          Eigen::Vector3i& close_point = nvoxel.closest_negative_point_;
          if (!isCellValid(close_point.x(), close_point.y(), close_point.z()))
          {
            close_point = nloc;
          }
          PropDistanceFieldVoxel& closest_point_voxel =
              voxel_grid_->getCell(close_point.x(), close_point.y(), close_point.z());

          // our closest non-obstacle cell has become an obstacle
          if (closest_point_voxel.negative_distance_square_ != 0)
          {
            // find all neighbors inside pre-existing obstacles whose
            // closest_negative_point_ is now an obstacle.  These must all be
            // set to max_distance_sq_ so they will be re-propogated with a new
            // closest_negative_point_ that is outside the obstacle.
            if (nvoxel.negative_distance_square_ != max_distance_sq_)
            {
              nvoxel.negative_distance_square_ = max_distance_sq_;
              nvoxel.closest_negative_point_.x() = PropDistanceFieldVoxel::UNINITIALIZED;
              nvoxel.closest_negative_point_.y() = PropDistanceFieldVoxel::UNINITIALIZED;
              nvoxel.closest_negative_point_.z() = PropDistanceFieldVoxel::UNINITIALIZED;
              negative_stack.push_back(nloc);
            }
          }
          else
          {
            // this cell still has a valid non-obstacle cell, so we need to propagate from it
            nvoxel.negative_update_direction_ = initial_update_direction;
            negative_bucket_queue_[0].push_back(nloc);
          }
        }
      }
    }
    propagateNegative();
  }
}

void PropagationDistanceField::removeObstacleVoxels(const EigenSTL::vector_Vector3i& voxel_points)
// const VoxelSet& locations )
{
  EigenSTL::vector_Vector3i stack;
  EigenSTL::vector_Vector3i negative_stack;
  int initial_update_direction = getDirectionNumber(0, 0, 0);

  stack.reserve(getXNumCells() * getYNumCells() * getZNumCells());
  bucket_queue_[0].reserve(voxel_points.size());
  if (propagate_negative_)
  {
    negative_stack.reserve(getXNumCells() * getYNumCells() * getZNumCells());
    negative_bucket_queue_[0].reserve(voxel_points.size());
  }

  // First reset the obstacle voxels,
  // VoxelSet::const_iterator it = locations.begin();
  // for( it=locations.begin(); it!=locations.end(); ++it)
  // {
  //   Eigen::Vector3i loc = *it;
  //   bool valid = isCellValid( loc.x(), loc.y(), loc.z());
  //   if (!valid)
  //     continue;
  for (const Eigen::Vector3i& voxel_point : voxel_points)
  {
    PropDistanceFieldVoxel& voxel = voxel_grid_->getCell(voxel_point.x(), voxel_point.y(), voxel_point.z());
    voxel.distance_square_ = max_distance_sq_;
    voxel.closest_point_ = voxel_point;
    voxel.update_direction_ = initial_update_direction;  // not needed?
    stack.push_back(voxel_point);
    if (propagate_negative_)
    {
      voxel.negative_distance_square_ = 0.0;
      voxel.closest_negative_point_ = voxel_point;
      voxel.negative_update_direction_ = initial_update_direction;
      negative_bucket_queue_[0].push_back(voxel_point);
    }
  }

  // Reset all neighbors who's closest point is now gone.
  while (!stack.empty())
  {
    Eigen::Vector3i loc = stack.back();
    stack.pop_back();

    for (int neighbor = 0; neighbor < 27; ++neighbor)
    {
      Eigen::Vector3i diff = getLocationDifference(neighbor);
      Eigen::Vector3i nloc(loc.x() + diff.x(), loc.y() + diff.y(), loc.z() + diff.z());

      if (isCellValid(nloc.x(), nloc.y(), nloc.z()))
      {
        PropDistanceFieldVoxel& nvoxel = voxel_grid_->getCell(nloc.x(), nloc.y(), nloc.z());
        Eigen::Vector3i& close_point = nvoxel.closest_point_;
        if (!isCellValid(close_point.x(), close_point.y(), close_point.z()))
        {
          close_point = nloc;
        }
        PropDistanceFieldVoxel& closest_point_voxel =
            voxel_grid_->getCell(close_point.x(), close_point.y(), close_point.z());

        if (closest_point_voxel.distance_square_ != 0)
        {  // closest point no longer exists
          if (nvoxel.distance_square_ != max_distance_sq_)
          {
            nvoxel.distance_square_ = max_distance_sq_;
            nvoxel.closest_point_ = nloc;
            nvoxel.update_direction_ = initial_update_direction;  // not needed?
            stack.push_back(nloc);
          }
        }
        else
        {  // add to queue so we can propagate the values
          nvoxel.update_direction_ = initial_update_direction;
          bucket_queue_[0].push_back(nloc);
        }
      }
    }
  }
  propagatePositive();

  if (propagate_negative_)
  {
    propagateNegative();
  }
}

void PropagationDistanceField::propagatePositive()
{
  // now process the queue:
  for (unsigned int i = 0; i < bucket_queue_.size(); ++i)
  {
    EigenSTL::vector_Vector3i::iterator list_it = bucket_queue_[i].begin();
    EigenSTL::vector_Vector3i::iterator list_end = bucket_queue_[i].end();
    for (; list_it != list_end; ++list_it)
    {
      const Eigen::Vector3i& loc = *list_it;
      PropDistanceFieldVoxel* vptr = &voxel_grid_->getCell(loc.x(), loc.y(), loc.z());

      // select the neighborhood list based on the update direction:
      EigenSTL::vector_Vector3i* neighborhood;
      int d = i;
      if (d > 1)
        d = 1;

      // This will never happen.  update_direction_ is always set before voxel is added to bucket queue.
      if (vptr->update_direction_ < 0 || vptr->update_direction_ > 26)
      {
        RCLCPP_ERROR(LOGGER, "PROGRAMMING ERROR: Invalid update direction detected: %d", vptr->update_direction_);
        continue;
      }

      neighborhood = &neighborhoods_[d][vptr->update_direction_];

      for (const Eigen::Vector3i& diff : *neighborhood)
      {
        Eigen::Vector3i nloc(loc.x() + diff.x(), loc.y() + diff.y(), loc.z() + diff.z());
        if (!isCellValid(nloc.x(), nloc.y(), nloc.z()))
          continue;

        // the real update code:
        // calculate the neighbor's new distance based on my closest filled voxel:
        PropDistanceFieldVoxel* neighbor = &voxel_grid_->getCell(nloc.x(), nloc.y(), nloc.z());
        int new_distance_sq = (vptr->closest_point_ - nloc).squaredNorm();
        if (new_distance_sq > max_distance_sq_)
          continue;

        if (new_distance_sq < neighbor->distance_square_)
        {
          // update the neighboring voxel
          neighbor->distance_square_ = new_distance_sq;
          neighbor->closest_point_ = vptr->closest_point_;
          neighbor->update_direction_ = getDirectionNumber(diff.x(), diff.y(), diff.z());

          // and put it in the queue:
          bucket_queue_[new_distance_sq].push_back(nloc);
        }
      }
    }
    bucket_queue_[i].clear();
  }
}

void PropagationDistanceField::propagateNegative()
{
  // now process the queue:
  for (unsigned int i = 0; i < negative_bucket_queue_.size(); ++i)
  {
    EigenSTL::vector_Vector3i::iterator list_it = negative_bucket_queue_[i].begin();
    EigenSTL::vector_Vector3i::iterator list_end = negative_bucket_queue_[i].end();
    for (; list_it != list_end; ++list_it)
    {
      const Eigen::Vector3i& loc = *list_it;
      PropDistanceFieldVoxel* vptr = &voxel_grid_->getCell(loc.x(), loc.y(), loc.z());

      // select the neighborhood list based on the update direction:
      EigenSTL::vector_Vector3i* neighborhood;
      int d = i;
      if (d > 1)
        d = 1;

      // This will never happen.  negative_update_direction_ is always set before voxel is added to
      // negative_bucket_queue_.
      if (vptr->negative_update_direction_ < 0 || vptr->negative_update_direction_ > 26)
      {
        RCLCPP_ERROR(LOGGER, "PROGRAMMING ERROR: Invalid update direction detected: %d", vptr->update_direction_);
        continue;
      }

      neighborhood = &neighborhoods_[d][vptr->negative_update_direction_];

      for (const Eigen::Vector3i& diff : *neighborhood)
      {
        Eigen::Vector3i nloc(loc.x() + diff.x(), loc.y() + diff.y(), loc.z() + diff.z());
        if (!isCellValid(nloc.x(), nloc.y(), nloc.z()))
          continue;

        // the real update code:
        // calculate the neighbor's new distance based on my closest filled voxel:
        PropDistanceFieldVoxel* neighbor = &voxel_grid_->getCell(nloc.x(), nloc.y(), nloc.z());
        int new_distance_sq = (vptr->closest_negative_point_ - nloc).squaredNorm();
        if (new_distance_sq > max_distance_sq_)
          continue;
        // std::cout << "Looking at " << nloc.x() << " " << nloc.y() << " " << nloc.z() << " " << new_distance_sq << " "
        // << neighbor->negative_distance_square_ << '\n';
        if (new_distance_sq < neighbor->negative_distance_square_)
        {
          // std::cout << "Updating " << nloc.x() << " " << nloc.y() << " " << nloc.z() << " " << new_distance_sq <<
          // '\n';
          // update the neighboring voxel
          neighbor->negative_distance_square_ = new_distance_sq;
          neighbor->closest_negative_point_ = vptr->closest_negative_point_;
          neighbor->negative_update_direction_ = getDirectionNumber(diff.x(), diff.y(), diff.z());

          // and put it in the queue:
          negative_bucket_queue_[new_distance_sq].push_back(nloc);
        }
      }
    }
    negative_bucket_queue_[i].clear();
  }
}

void PropagationDistanceField::reset()
{
  voxel_grid_->reset(PropDistanceFieldVoxel(max_distance_sq_, 0));
  for (int x = 0; x < getXNumCells(); ++x)
  {
    for (int y = 0; y < getYNumCells(); ++y)
    {
      for (int z = 0; z < getZNumCells(); ++z)
      {
        PropDistanceFieldVoxel& voxel = voxel_grid_->getCell(x, y, z);
        voxel.closest_negative_point_.x() = x;
        voxel.closest_negative_point_.y() = y;
        voxel.closest_negative_point_.z() = z;
        voxel.negative_distance_square_ = 0;
      }
    }
  }
  // object_voxel_locations_.clear();
}

void PropagationDistanceField::initNeighborhoods()
{
  // first initialize the direction number mapping:
  direction_number_to_direction_.resize(27);
  for (int dx = -1; dx <= 1; ++dx)
  {
    for (int dy = -1; dy <= 1; ++dy)
    {
      for (int dz = -1; dz <= 1; ++dz)
      {
        int direction_number = getDirectionNumber(dx, dy, dz);
        Eigen::Vector3i n_point(dx, dy, dz);
        direction_number_to_direction_[direction_number] = n_point;
      }
    }
  }

  neighborhoods_.resize(2);
  for (int n = 0; n < 2; ++n)
  {
    neighborhoods_[n].resize(27);
    // source directions
    for (int dx = -1; dx <= 1; ++dx)
    {
      for (int dy = -1; dy <= 1; ++dy)
      {
        for (int dz = -1; dz <= 1; ++dz)
        {
          int direction_number = getDirectionNumber(dx, dy, dz);
          // target directions:
          for (int tdx = -1; tdx <= 1; ++tdx)
          {
            for (int tdy = -1; tdy <= 1; ++tdy)
            {
              for (int tdz = -1; tdz <= 1; ++tdz)
              {
                if (tdx == 0 && tdy == 0 && tdz == 0)
                  continue;
                if (n >= 1)
                {
                  if ((abs(tdx) + abs(tdy) + abs(tdz)) != 1)
                    continue;
                  if (dx * tdx < 0 || dy * tdy < 0 || dz * tdz < 0)
                    continue;
                }
                Eigen::Vector3i n_point(tdx, tdy, tdz);
                neighborhoods_[n][direction_number].push_back(n_point);
              }
            }
          }
          // printf("n=%d, dx=%d, dy=%d, dz=%d, neighbors = %d\n", n, dx, dy, dz,
          // neighborhoods_[n][direction_number].size());
        }
      }
    }
  }
}

int PropagationDistanceField::getDirectionNumber(int dx, int dy, int dz) const
{
  return (dx + 1) * 9 + (dy + 1) * 3 + dz + 1;
}

Eigen::Vector3i PropagationDistanceField::getLocationDifference(int directionNumber) const
{
  return direction_number_to_direction_[directionNumber];
}

double PropagationDistanceField::getDistance(double x, double y, double z) const
{
  return getDistance((*voxel_grid_.get())(x, y, z));
}

double PropagationDistanceField::getDistance(int x, int y, int z) const
{
  return getDistance(voxel_grid_->getCell(x, y, z));
}

bool PropagationDistanceField::isCellValid(int x, int y, int z) const
{
  return voxel_grid_->isCellValid(x, y, z);
}

int PropagationDistanceField::getXNumCells() const
{
  return voxel_grid_->getNumCells(DIM_X);
}

int PropagationDistanceField::getYNumCells() const
{
  return voxel_grid_->getNumCells(DIM_Y);
}

int PropagationDistanceField::getZNumCells() const
{
  return voxel_grid_->getNumCells(DIM_Z);
}

bool PropagationDistanceField::gridToWorld(int x, int y, int z, double& world_x, double& world_y, double& world_z) const
{
  voxel_grid_->gridToWorld(x, y, z, world_x, world_y, world_z);
  return true;
}

bool PropagationDistanceField::worldToGrid(double world_x, double world_y, double world_z, int& x, int& y, int& z) const
{
  return voxel_grid_->worldToGrid(world_x, world_y, world_z, x, y, z);
}

bool PropagationDistanceField::writeToStream(std::ostream& os) const
{
  os << "resolution: " << resolution_ << '\n';
  os << "size_x: " << size_x_ << '\n';
  os << "size_y: " << size_y_ << '\n';
  os << "size_z: " << size_z_ << '\n';
  os << "origin_x: " << origin_x_ << '\n';
  os << "origin_y: " << origin_y_ << '\n';
  os << "origin_z: " << origin_z_ << '\n';
  // now the binary stuff

  // first writing to zlib compressed buffer
  boost::iostreams::filtering_ostream out;
  out.push(boost::iostreams::zlib_compressor());
  out.push(os);

  for (unsigned int x = 0; x < static_cast<unsigned int>(getXNumCells()); ++x)
  {
    for (unsigned int y = 0; y < static_cast<unsigned int>(getYNumCells()); ++y)
    {
      for (unsigned int z = 0; z < static_cast<unsigned int>(getZNumCells()); z += 8)
      {
        std::bitset<8> bs(0);
        unsigned int zv = std::min((unsigned int)8, getZNumCells() - z);
        for (unsigned int zi = 0; zi < zv; ++zi)
        {
          if (getCell(x, y, z + zi).distance_square_ == 0)
          {
            // std::cout << "Marking obs cell " << x << " " << y << " " << z+zi << '\n';
            bs[zi] = 1;
          }
        }
        out.write((char*)&bs, sizeof(char));
      }
    }
  }
  out.flush();
  return true;
}

bool PropagationDistanceField::readFromStream(std::istream& is)
{
  if (!is.good())
    return false;

  std::string temp;

  is >> temp;
  if (temp != "resolution:")
    return false;
  is >> resolution_;

  is >> temp;
  if (temp != "size_x:")
    return false;
  is >> size_x_;

  is >> temp;
  if (temp != "size_y:")
    return false;
  is >> size_y_;

  is >> temp;
  if (temp != "size_z:")
    return false;
  is >> size_z_;

  is >> temp;
  if (temp != "origin_x:")
    return false;
  is >> origin_x_;

  is >> temp;
  if (temp != "origin_y:")
    return false;
  is >> origin_y_;

  is >> temp;
  if (temp != "origin_z:")
    return false;
  is >> origin_z_;

  // previous values for propogation_negative_ and max_distance_ will be used

  initialize();

  // this should be newline
  char nl;
  is.get(nl);

  // now we start the compressed portion
  boost::iostreams::filtering_istream in;
  in.push(boost::iostreams::zlib_decompressor());
  in.push(is);

  // std::cout << "Nums " << getXNumCells() << " " << getYNumCells() << " " << getZNumCells() << '\n';

  EigenSTL::vector_Vector3i obs_points;
  for (unsigned int x = 0; x < static_cast<unsigned int>(getXNumCells()); ++x)
  {
    for (unsigned int y = 0; y < static_cast<unsigned int>(getYNumCells()); ++y)
    {
      for (unsigned int z = 0; z < static_cast<unsigned int>(getZNumCells()); z += 8)
      {
        char inchar;
        if (!in.good())
        {
          return false;
        }
        in.get(inchar);
        std::bitset<8> inbit((unsigned long long)inchar);
        unsigned int zv = std::min((unsigned int)8, getZNumCells() - z);
        for (unsigned int zi = 0; zi < zv; ++zi)
        {
          if (inbit[zi] == 1)
          {
            // std::cout << "Adding obs cell " << x << " " << y << " " << z+zi << '\n';
            obs_points.push_back(Eigen::Vector3i(x, y, z + zi));
          }
        }
      }
    }
  }
  addNewObstacleVoxels(obs_points);
  return true;
}
}  // namespace distance_field

ext: cpp


text:
#pragma once

#include "Bitmap.hpp"
#include "ScanlineBuffer.hpp"
#include "Shader.hpp"

#include <Eigen/StdVector>
#include <vector>

template <typename T>
using EigenVec = std::vector<T, Eigen::aligned_allocator<T>>;

namespace LRR
{
  namespace Rendering
  {
    using namespace Eigen;

    class Rasterizer final
    {
    private:
      using BitmapT = Rendering::Bitmap;
    public:
      Rasterizer() = delete;
      Rasterizer(int frameWidth, int frameHeight);
      ~Rasterizer() = default;

      inline BitmapT &Bitmap()
      { return mFrameBuffer; }

      inline void Clear(uint32_t color) {
        mFrameBuffer.Clear(color);
      }

      void DrawTriangle(Vector3f const &a, Vector3f const &b, Vector3f const &c, Shader &shader);
    private:
      void DrawScanlineBuffer(int x, int y, ScanlineBuffer const &slBuffer, Shader &shader);
      static void ClipPolygonComponent(EigenVec<Vector4f> const &vertices, EigenVec<Vector4f> &clippedOut, unsigned componentIndex, float factor);
      static bool ClipPolygonAxis(EigenVec<Vector4f> &vertices, EigenVec<Vector4f> &auxList, unsigned componentIndex);
      void FillTriangle(Vector3f const &a, Vector3f const &b, Vector3f const &c, Shader &shader);

      BitmapT mFrameBuffer;
    };
  }
}

ext: hpp

max_stars_repo_name: Lisoph/LowResRenderer

max_issues_repo_name: Lisoph/LowResRenderer

max_forks_repo_name: Lisoph/LowResRenderer


text:
/// @file  svmlight.cpp
/// @brief I/O tools for svmlight files.
///
/// See the documentation at http://svmlight.joachims.org.
/// To quote from their description of the file format:
///
/// The input file example_file contains the training examples. The first lines
/// may contain comments and are ignored if they start with #. Each of the
/// following lines represents one training example and is of the following
/// format:
///
/// <line> .=. <target> <feature>:<value> ... <feature>:<value> # <info>
/// <target> .=. +1 | -1 | 0 | <float>
/// <feature> .=. <integer> | "qid"
/// <value> .=. <float>
/// <info> .=. <string>
///
/// The target value and each of the feature/value pairs are separated by a
/// space character. Feature/value pairs MUST be ordered by increasing feature
/// number. Features with value zero can be skipped. The string <info> can be
/// used to pass additional information to the kernel (e.g. non feature
/// vector data).

#include <ordgeo/io/io.hpp>
#include <cstdlib>
#include <fstream>
#include <sstream>
#include <vector>
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#include <boost/compute/detail/lru_cache.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
#pragma GCC diagnostic pop

using boost::compute::detail::lru_cache;
using boost::phoenix::push_back;
using boost::spirit::ascii::space;
using boost::spirit::istream_iterator;
using boost::spirit::qi::_1;
using boost::spirit::qi::double_;
using boost::spirit::qi::eol;
using boost::spirit::qi::int_;
using boost::spirit::qi::phrase_parse;
using Eigen::SparseMatrix;
using std::atof;
using std::atoi;
using std::ifstream;
using std::istream;
using std::shared_ptr;
using std::string;
using std::stringstream;
using std::vector;

namespace ORDGEO_NAMESPACE {
namespace io {

/// Allows row-by-row access to a very large sparse data file.
class SvmLightScanner : public SparseScanner {
public:

	/// Instantiate a new scanner from the specified file path
	SvmLightScanner(std::string name)
		: fin(openSource(name))
		, nRow(-1)
		, nCols(0)
		, maxRows(0)
		, gotEof(false)
		, cache(10000)
	{
	}

	/// Move to the beginning of the file.
	void reset() override {
		fin->clear();
		fin->seekg(0);
		nRow = -1;
	}

	/// Truncate the matrix to the specified number of rows.
	void truncate(size_t nRows) override {
		if (maxRows > 0 && nRows < maxRows) {
			maxRows = nRows;
		}
	}

	/// Get the (zero-based) index of the most recently-read row from the file.
	size_t nrow() override {
		return nRow;
	}

	/// Get the number of rows in the file.
	size_t rows() override {
		if (!gotEof) {
			const auto atRow = nRow;
			const auto pos = fin->tellg();
			while (!eof()) {
				read();
			}
			fin->clear();
			fin->seekg(pos);
			nRow = atRow;
		}
		return rowPos.size();
	}

	/// Get the number of columns in the file.
	size_t cols() override {
		if (!gotEof) {
			const auto pos = fin->tellg();
			while (!eof()) {
				read();
			}
			fin->clear();
			fin->seekg(pos);
		}
		return nCols;
	}

	/// Ask whether there is another vector in the file.
	bool eof() override {
		return fin->bad() || fin->eof();
	}

	/// Get the next vector from the file.
	SparseScanner::VT read() override {

		// Try to read the next line of input
		if ((maxRows > 0 && nRow >= static_cast<int>(maxRows - 1)) || eof()) {
			gotEof = true;
			return SparseScanner::VT();
		}
		string line;
		auto pos = fin->tellg();
		while (line == "") {
			getline(*fin, line);
			if (eof()) {
				gotEof = true;
				return SparseScanner::VT();
			} else if (line == "") {
				pos = fin->tellg();
			}
		}

		// Parse the row
		nRow++;
		if (static_cast<size_t>(nRow) >= rowPos.size()) {
			rowPos.push_back(pos);
		}

		bool first = true;
		typedef Eigen::Triplet<double> T;
		std::vector<T> tripletList;
		size_t spacePos = line.find(' ');
		while (spacePos != std::string::npos) {
			if (first) {
				// skip the target
				first = false;
				spacePos = line.find(' ', spacePos);
			} else {
				size_t colPos = line.find(':', spacePos + 1);
				if (colPos == std::string::npos) {
					spacePos = colPos;
				} else {
					string sidx = line.substr(spacePos + 1, colPos);
					if (sidx.find("qid") != string::npos) {
						spacePos = line.find(' ', colPos + 1);
						continue;
					}
					int idx = atoi(sidx.c_str());
					spacePos = line.find(' ', colPos + 1);
					double val = atof(line.substr(colPos + 1, spacePos).c_str());

					tripletList.emplace_back(0, idx, val);
					if (idx >= static_cast<int>(nCols)) {
						nCols = idx + 1;
					}
				}
			}
		}

		SparseScanner::VT vec(nCols);
		for (const auto& trip : tripletList) {
			vec.coeffRef(trip.col()) += trip.value();
		}
		return vec;
	}

	/// Get the specified vector from the file. May trigger a file scan.
	SparseScanner::VT row(size_t row) override {
		auto cached = cache.get(row);
		if (cached != boost::none) {
			return *cached;
		}
		if (row >= rowPos.size()) {
			while (!eof() && row >= rowPos.size()) {
				auto vec = read();
				if (row == static_cast<size_t>(nRow)) {
					cache.insert(row, vec);
					return vec;
				}
			}
			return SparseScanner::VT();
		} else {
			nRow = static_cast<int>(row) - 1;
			fin->clear();
			fin->seekg(rowPos[row]);
			auto vec = read();
			cache.insert(row, vec);
			return vec;
		}
	}

private:
	std::shared_ptr<istream> fin;
	int nRow;
	size_t nCols;
	size_t maxRows;
	vector<std::istream::pos_type> rowPos;
	bool gotEof;
	lru_cache<size_t, SparseScanner::VT> cache;
};

/// Get a scanner for a svmlight file
shared_ptr<SparseScanner> openSvmLightScanner(std::string name) {
	return std::make_shared<SvmLightScanner>(name);
}

} // end namespace io
} // end namespace ORDGEO_NAMESPACE

max_stars_repo_name: jesand/ordgeo

max_issues_repo_name: jesand/ordgeo

max_forks_repo_name: jesand/ordgeo


text:
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2011-2015  Regents of the University of California.
 *
 * This file is part of ndnSIM. See AUTHORS for complete list of ndnSIM authors and
 * contributors.
 *
 * ndnSIM is free software: you can redistribute it and/or modify it under the terms
 * of the GNU General Public License as published by the Free Software Foundation,
 * either version 3 of the License, or (at your option) any later version.
 *
 * ndnSIM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 * PURPOSE.  See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * ndnSIM, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
 **/

#ifndef MULTI_POLICY_CONTAINER_H_
#define MULTI_POLICY_CONTAINER_H_

/// @cond include_hidden

#include <boost/mpl/inherit_linearly.hpp>
#include <boost/mpl/at.hpp>

namespace ns3 {
namespace ndn {
namespace ndnSIM {
namespace detail {

template<class Base, class Value>
struct policy_wrap {
  policy_wrap(Base& base)
    : value_(base)
  {
  }
  Value value_;
};

template<class Base, class Super /*empy_wrap/previous level*/,
         class Value /*policy_wrap< element in vector >*/>
struct inherit_with_base : Super, Value {
  inherit_with_base(Base& base)
    : Super(base)
    , Value(base)
  {
  }

  void
  update(typename Base::iterator item)
  {
    Value::value_.update(item);
    Super::update(item);
  }

  bool
  insert(typename Base::iterator item)
  {
    bool ok = Value::value_.insert(item);
    if (!ok)
      return false;

    ok = Super::insert(item);
    if (!ok) {
      Value::value_.erase(item);
      return false;
    }
    return true;
  }

  void
  lookup(typename Base::iterator item)
  {
    Value::value_.lookup(item);
    Super::lookup(item);
  }

  void
  erase(typename Base::iterator item)
  {
    Value::value_.erase(item);
    Super::erase(item);
  }

  void
  clear()
  {
    Value::value_.clear();
    Super::clear();
  }
};

template<class Base>
struct empty_policy_wrap {
  empty_policy_wrap(Base& base)
  {
  }

  void
  update(typename Base::iterator item)
  {
  }
  bool
  insert(typename Base::iterator item)
  {
    return true;
  }
  void
  lookup(typename Base::iterator item)
  {
  }
  void
  erase(typename Base::iterator item)
  {
  }
  void
  clear()
  {
  }
};

template<class Base, class Vector>
struct multi_policy_container
  : public boost::mpl::
      fold<Vector, empty_policy_wrap<Base>,
           inherit_with_base<Base, boost::mpl::_1 /*empty/previous*/,
                             policy_wrap<Base, boost::mpl::_2> /*element in vector*/>>::type {
  typedef typename boost::mpl::
    fold<Vector, empty_policy_wrap<Base>,
         inherit_with_base<Base, boost::mpl::_1 /*empty/previous*/,
                           policy_wrap<Base, boost::mpl::_2> /*element in vector*/>>::type super;

  typedef typename boost::mpl::at_c<Vector, 0>::type::iterator iterator;
  typedef typename boost::mpl::at_c<Vector, 0>::type::const_iterator const_iterator;

  iterator
  begin()
  {
    return this->get<0>().begin();
  }
  const_iterator
  begin() const
  {
    return this->get<0>().begin();
  }

  iterator
  end()
  {
    return this->get<0>().end();
  }
  const_iterator
  end() const
  {
    return this->get<0>().end();
  }

  size_t
  size() const
  {
    return this->get<0>().size();
  }

  multi_policy_container(Base& base)
    : super(base)
  {
  }

  template<int N>
  struct index {
    typedef typename boost::mpl::at_c<Vector, N>::type type;
  };

  template<class T>
  T&
  get()
  {
    return static_cast<policy_wrap<Base, T>&>(*this).value_;
  }

  template<class T>
  const T&
  get() const
  {
    return static_cast<const policy_wrap<Base, T>&>(*this).value_;
  }

  template<int N>
  typename boost::mpl::at_c<Vector, N>::type&
  get()
  {
    typedef typename boost::mpl::at_c<Vector, N>::type T;
    return static_cast<policy_wrap<Base, T>&>(*this).value_;
  }

  template<int N>
  const typename boost::mpl::at_c<Vector, N>::type&
  get() const
  {
    typedef typename boost::mpl::at_c<Vector, N>::type T;
    return static_cast<const policy_wrap<Base, T>&>(*this).value_;
  }
};

} // detail
} // ndnSIM
} // ndn
} // ns3

/// @endcond

#endif // MULTI_POLICY_CONTAINER_H_

max_stars_repo_name: seanbraley/ndn-split-caching

max_issues_repo_name: seanbraley/ndn-split-caching

max_forks_repo_name: seanbraley/ndn-split-caching


text:
/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

#include "ApkResources.h"
#include "RedexTestUtils.h"

#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include <boost/filesystem.hpp>

TEST(ManifestClassesTest, exported) {
  // Setup a normal looking apk directory
  auto tmp_dir = redex::make_tmp_dir("ManifestClassesTest%%%%%%%%");
  std::ifstream src_stream(std::getenv("test_manifest_path"), std::ios::binary);
  auto dest = tmp_dir.path + "/AndroidManifest.xml";
  {
    std::ofstream dest_stream(dest, std::ios::binary);
    dest_stream << src_stream.rdbuf();
  }

  ApkResources resources(tmp_dir.path);
  const auto& class_info = resources.get_manifest_class_info();

  const auto& tag_infos = class_info.component_tags;
  EXPECT_EQ(tag_infos.size(), 5);

  EXPECT_EQ(tag_infos[0].tag, ComponentTag::Activity);
  EXPECT_EQ(tag_infos[0].classname, "Ltest1;");
  EXPECT_EQ(tag_infos[0].is_exported, BooleanXMLAttribute::True);
  EXPECT_FALSE(tag_infos[0].has_intent_filters);

  EXPECT_EQ(tag_infos[1].tag, ComponentTag::Activity);
  EXPECT_EQ(tag_infos[1].classname, "Ltest2;");
  EXPECT_EQ(tag_infos[1].is_exported, BooleanXMLAttribute::Undefined);
  EXPECT_FALSE(tag_infos[1].has_intent_filters);

  EXPECT_EQ(tag_infos[2].tag, ComponentTag::Activity);
  EXPECT_EQ(tag_infos[2].classname, "Ltest3;");
  EXPECT_EQ(tag_infos[2].is_exported, BooleanXMLAttribute::Undefined);
  EXPECT_TRUE(tag_infos[2].has_intent_filters);

  EXPECT_EQ(tag_infos[3].tag, ComponentTag::Activity);
  EXPECT_EQ(tag_infos[3].classname, "Ltest4;");
  EXPECT_EQ(tag_infos[3].is_exported, BooleanXMLAttribute::False);
  EXPECT_FALSE(tag_infos[3].has_intent_filters);

  EXPECT_EQ(tag_infos[4].tag, ComponentTag::Provider);
  EXPECT_EQ(tag_infos[4].classname, "Lcom/example/x/Foo;");
  EXPECT_EQ(tag_infos[4].is_exported, BooleanXMLAttribute::Undefined);
  EXPECT_THAT(tag_infos[4].authority_classes,
              ::testing::UnorderedElementsAre("Lcom/example/x/Foo;",
                                              "Lcom/example/y/Bar;"));
}

max_stars_repo_name: jimmycFB/redex

max_issues_repo_name: jimmycFB/redex

max_forks_repo_name: jimmycFB/redex


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

#include "fixtures.h"
#include <stdexcept>

using std::string;

using lua::Retval;
using lua::Context;
using lua::Value;
using lua::Table;
using lua::Valset;
using lua::mkcf;

struct Udata{int x;};
LUAPP_USERDATA(Udata, "Test.Userdata")

struct SpecialType{int x;};
LUAPP_ARG_CONVERT(SpecialType, {return SpecialType{val.cast<int>()};})
LUAPP_RV_CONVERT(SpecialType, {return context.ret(val.x);})

BOOST_AUTO_TEST_SUITE(ContextFunctionUtility)

static Retval closureTest(Context& context)
{
	return context.ret(
		context.args.size() == 3 &&
		context.args[0].is<int>() &&
		context.args[0].cast<int>() == 1 &&
		context.args[1].is<string>() &&
		context.args[1].cast<string>() == "a string" &&
		context.args[2].is<Udata>() &&
		context.args[2].cast<Udata>().x == 3 &&
		context.upvalues[1].is<int>() &&
		context.upvalues[1].cast<int>() == 1 &&
		context.upvalues[2].is<string>() &&
		context.upvalues[2].cast<string>() == "a string" &&
		context.upvalues[3].is<Udata>() &&
		context.upvalues[3].cast<Udata>().x == 3
	);
}

BOOST_FIXTURE_TEST_CASE(CreateClosure, fxContext)
{
	context.mt<Udata>() = Table::records(context);
	Value c = context.closure(mkcf<closureTest>, 1, "a string", Udata{3});
	const bool result = c(1, "a string", Udata{3});
	BOOST_CHECK(result);
}

BOOST_FIXTURE_TEST_CASE(CreateChunkFromString, fxContext)
{
	Value c = context.chunk("return 1, \"a string\"");
	Valset result = c.pcall();
	BOOST_CHECK(result.success());
	BOOST_CHECK_EQUAL(result.size(), 2);
	BOOST_CHECK_EQUAL(result[0].cast<int>(), 1);
	BOOST_CHECK_EQUAL(result[1].cast<string>(), "a string");
	BOOST_CHECK_THROW(Value v = context.chunk("{"), std::runtime_error);		// Chunk creators are discardable
}

BOOST_FIXTURE_TEST_CASE(CreateChunkFromStdString, fxContext)
{
	Value c = context.chunk(string("return 1, \"a string\""));
	Valset result = c.pcall();
	BOOST_CHECK(result.success());
	BOOST_CHECK_EQUAL(result.size(), 2);
	BOOST_CHECK_EQUAL(result[0].cast<int>(), 1);
	BOOST_CHECK_EQUAL(result[1].cast<string>(), "a string");
	BOOST_CHECK_THROW(Value v = context.chunk(string("{")), std::runtime_error);		// Chunk creators are discardable
}

BOOST_FIXTURE_TEST_CASE(CreateChunkFromFile, fxFiles)
{
	context.runString("function fnSignal() signal = true end");
	Value c = context.load("test_good.lua");
	c();
	BOOST_CHECK(context.global["signal"].cast<bool>());
	BOOST_CHECK_THROW(Value v = context.load("test_bad.lua"), std::runtime_error);	// Chunk creators are discardable
	BOOST_CHECK_THROW(Value v = context.load("nosuchfile.lua"), std::runtime_error);
}

BOOST_FIXTURE_TEST_CASE(CreateChunkFromFileStdStr, fxFiles)
{
	context.runString(string("function fnSignal() signal = true end"));
	Value c = context.load(string("test_good.lua"));
	c();
	BOOST_CHECK(context.global["signal"].cast<bool>());
	BOOST_CHECK_THROW(Value v = context.load(string("test_bad.lua")), std::runtime_error);	// Chunk creators are discardable
	BOOST_CHECK_THROW(Value v = context.load(string("nosuchfile.lua")), std::runtime_error);
}

BOOST_FIXTURE_TEST_CASE(RunString, fxContext)
{
	BOOST_CHECK_THROW(context.runString("{"), std::runtime_error);
	BOOST_CHECK_THROW(context.runString(string("{")), std::runtime_error);
}

BOOST_FIXTURE_TEST_CASE(RunFile, fxFiles)
{
	context.runString("function fnSignal() signal = true end");
	context.runFile("test_good.lua");
	BOOST_CHECK(context.global["signal"].cast<bool>());
	BOOST_CHECK_THROW(context.runFile("test_bad.lua"), std::runtime_error);
	BOOST_CHECK_THROW(context.runFile("nosuchfile.lua"), std::runtime_error);
}

BOOST_FIXTURE_TEST_CASE(RunFileStdStr, fxFiles)
{
	context.runString(string("function fnSignal() signal = true end"));
	context.runFile(string("test_good.lua"));
	BOOST_CHECK(context.global["signal"].cast<bool>());
	BOOST_CHECK_THROW(context.runFile(string("test_bad.lua")), std::runtime_error);
	BOOST_CHECK_THROW(context.runFile(string("nosuchfile.lua")), std::runtime_error);
}

static int signal = 0;
static int wrapped1(int x) {return x*3;}
static void wrapped0(const Udata& x) {signal = x.x;}
static int vwrapped(const string& x, int y) {signal = x.size() + y; return 0;}

BOOST_FIXTURE_TEST_CASE(SimpleWrappers, fxContext)
{
	context.mt<Udata>() = Table::records(context);
	context.global["fn"] = context.wrap(wrapped1);
	BOOST_CHECK_EQUAL(context.global["fn"](3).cast<int>(), 9);
	{
		Valset vs = context.global["fn"].pcall();
		BOOST_CHECK(!vs.success());
	}

	context.global["fn"] = context.wrap(wrapped0);
	context.global["fn"](Udata{3});
	BOOST_CHECK_EQUAL(signal, 3);
	{
		Valset vs = context.global["fn"].pcall(1);
		BOOST_REQUIRE(!vs.success());
	}

	context.global["fn"] = context.vwrap(vwrapped);
	context.global["fn"]("12345", 4);
	BOOST_CHECK_EQUAL(signal, 9);
}

static SpecialType swrapped1(SpecialType x) {return SpecialType{x.x*3};}
static void swrapped0(const SpecialType& x) {signal = x.x;}
static int svwrapped(const SpecialType& x, int y) {signal = x.x + y; return 0;}

BOOST_FIXTURE_TEST_CASE(CustomWrappers, fxContext)
{
	context.global["fn"] = context.wrap(swrapped1);
	BOOST_CHECK_EQUAL(context.global["fn"](3).cast<int>(), 9);
	{
		Valset vs = context.global["fn"].pcall();
		BOOST_CHECK(!vs.success());
	}

	signal = 0;
	context.global["fn"] = context.wrap(swrapped0);
	context.global["fn"](3);
	BOOST_CHECK_EQUAL(signal, 3);

	context.global["fn"] = context.vwrap(svwrapped);
	context.global["fn"](5, 4);
	BOOST_CHECK_EQUAL(signal, 9);
}

BOOST_AUTO_TEST_SUITE_END()


text:
#include "AvenueSmoothMessage.h"
#include <boost/asio.hpp>
#include "Cipher.h"
#include <boost/thread/mutex.hpp>
#include <string>

using std::string;

using sdo::dbp::CCipher;

namespace sdo{
namespace commonsdk{
static boost::mutex s_mutexSequence;
unsigned int CAvenueSmoothEncoder::sm_dwSeq=0;
CAvenueSmoothEncoder::CAvenueSmoothEncoder()
{
    SAvenueMsgHeader *pHeader=(SAvenueMsgHeader *)m_buffer.base();
    pHeader->byContext=0;
	pHeader->byPrio=0;
	pHeader->byBodyType=0;
	pHeader->byCharset=0;

    pHeader->byHeadLen=sizeof(SAvenueMsgHeader);
    pHeader->dwPacketLen=htonl(sizeof(SAvenueMsgHeader));
    pHeader->byVersion=0x01;
    pHeader->byM=0xFF;
    pHeader->dwCode=0;
    memset(pHeader->bySignature,0,16);
    m_buffer.reset_loc(sizeof(SAvenueMsgHeader));
}
CAvenueSmoothEncoder::CAvenueSmoothEncoder(unsigned char byIdentifer,unsigned int dwServiceId,unsigned int dwMsgId,unsigned int dwCode)
{
    SAvenueMsgHeader *pHeader=(SAvenueMsgHeader *)m_buffer.base();
    pHeader->byContext=0;
	pHeader->byPrio=0;
	pHeader->byBodyType=0;
	pHeader->byCharset=0;

    pHeader->byHeadLen=sizeof(SAvenueMsgHeader);
    pHeader->dwPacketLen=htonl(sizeof(SAvenueMsgHeader));
    pHeader->byVersion=0x01;
    pHeader->byM=0xFF;
    pHeader->dwCode=0;
    memset(pHeader->bySignature,0,16);
    m_buffer.reset_loc(sizeof(SAvenueMsgHeader));

    pHeader->byIdentifer=byIdentifer;
    pHeader->dwServiceId=htonl(dwServiceId);
    pHeader->dwMsgId=htonl(dwMsgId);
    pHeader->dwCode=htonl(dwCode);

}
void CAvenueSmoothEncoder::Reset()
{
    SAvenueMsgHeader *pHeader=(SAvenueMsgHeader *)m_buffer.base();
    pHeader->byContext=0;
	pHeader->byPrio=0;
	pHeader->byBodyType=0;
	pHeader->byCharset=0;

    pHeader->byHeadLen=sizeof(SAvenueMsgHeader);
    pHeader->dwPacketLen=htonl(sizeof(SAvenueMsgHeader));
    pHeader->byVersion=0x01;
    pHeader->byM=0xFF;
    pHeader->dwCode=0;
    memset(pHeader->bySignature,0,16);
    m_buffer.reset_loc(sizeof(SAvenueMsgHeader));
}
void CAvenueSmoothEncoder::SetService(unsigned char byIdentifer,unsigned int dwServiceId,unsigned int dwMsgId,unsigned int dwCode)
{
    SAvenueMsgHeader *pHeader=(SAvenueMsgHeader *)m_buffer.base();
    pHeader->byIdentifer=byIdentifer;
    pHeader->dwServiceId=htonl(dwServiceId);
    pHeader->dwMsgId=htonl(dwMsgId);
    pHeader->dwCode=htonl(dwCode);
}
unsigned int CAvenueSmoothEncoder::CreateAndSetSequence()
{
    unsigned int dwSequnece;
    {
        boost::lock_guard<boost::mutex> guard(s_mutexSequence);
        if(++sm_dwSeq==0)
            sm_dwSeq++;
        dwSequnece=sm_dwSeq;
    }
    SetSequence(dwSequnece);
    return dwSequnece;
}
void CAvenueSmoothEncoder::SetSequence(unsigned int dwSequence)
{
    SAvenueMsgHeader *pHeader=(SAvenueMsgHeader *)m_buffer.base();
    pHeader->dwSequence=htonl(dwSequence);
}

void CAvenueSmoothEncoder::SetMsgOption(unsigned int dwOption)
{
   // SDK_XLOG(XLOG_DEBUG, "CAvenueSmoothEncoder::%s\n",__FUNCTION__);
    unsigned char * pOption=(unsigned char *)(&dwOption);
    SAvenueMsgHeader *pHeader=(SAvenueMsgHeader *)m_buffer.base();
    pHeader->byContext=pOption[0];
	pHeader->byPrio=pOption[1];
	pHeader->byBodyType=pOption[2];
	pHeader->byCharset=pOption[3];
}
void CAvenueSmoothEncoder::SetExtHeader(const void *pBuffer, unsigned int nLen)
{
    SAvenueMsgHeader *pHeader=(SAvenueMsgHeader *)m_buffer.base();
    pHeader->byHeadLen=sizeof(SAvenueMsgHeader)+nLen;
    memcpy(m_buffer.top(),pBuffer,nLen);
    m_buffer.inc_loc(nLen);
    pHeader->dwPacketLen=htonl(m_buffer.len());
}
void CAvenueSmoothEncoder::SetBody(const void *pBuffer, unsigned int nLen)
{
    if(m_buffer.capacity()<nLen)
    {
        m_buffer.add_capacity(SAP_ALIGN(nLen-m_buffer.capacity()));
    }
    SAvenueMsgHeader *pHeader=(SAvenueMsgHeader *)m_buffer.base();
    memcpy(m_buffer.top(),pBuffer,nLen);
    m_buffer.inc_loc(nLen);
    pHeader->dwPacketLen=htonl(m_buffer.len());
}
void CAvenueSmoothEncoder::AesEnc(unsigned char abyKey[16])
{
    SAvenueMsgHeader *pHeader=(SAvenueMsgHeader *)m_buffer.base();
    unsigned int nLeft=0x10-(m_buffer.len()-pHeader->byHeadLen)&0x0f;
    if(m_buffer.capacity()<nLeft)
    {
        m_buffer.add_capacity(SAP_ALIGN(nLeft-m_buffer.capacity()));
    }
    pHeader=(SAvenueMsgHeader *)m_buffer.base();
    memset(m_buffer.top(),0,nLeft);
    m_buffer.inc_loc(nLeft);
    unsigned char *pbyInBlk=(unsigned char *)m_buffer.base()+pHeader->byHeadLen;
    CCipher::AesEnc(abyKey,pbyInBlk,m_buffer.len()-pHeader->byHeadLen,pbyInBlk);
    pHeader->dwPacketLen=htonl(m_buffer.len());
}
void CAvenueSmoothEncoder::SetSignature(const char * szKey, unsigned int nLen)
{
    SAvenueMsgHeader *pHeader=(SAvenueMsgHeader *)m_buffer.base();
    int nMin=(nLen<16?nLen:16);
    memcpy(pHeader->bySignature,szKey,nMin);
    CCipher::Md5(m_buffer.base(),m_buffer.len(),pHeader->bySignature);
}
void CAvenueSmoothEncoder::SetValue(unsigned short wKey,const void* pValue,unsigned int nValueLen)
{
    unsigned int nFactLen=((nValueLen&0x03)!=0?((nValueLen>>2)+1)<<2:nValueLen);
    if(m_buffer.capacity()<nFactLen+4)
    {
        m_buffer.add_capacity(SAP_ALIGN(nFactLen+4-m_buffer.capacity()));
    }
    SAvenueMsgHeader *pHeader=(SAvenueMsgHeader *)m_buffer.base();
    SAvenueMsgAttribute *pAtti=(SAvenueMsgAttribute *)m_buffer.top();
    pAtti->wType=htons(wKey);
    pAtti->wLength=htons(nValueLen+sizeof(SAvenueMsgAttribute));
    memcpy(pAtti->acValue,pValue,nValueLen);
    memset(pAtti->acValue+nValueLen,0,nFactLen-nValueLen);
    m_buffer.inc_loc(sizeof(SAvenueMsgAttribute)+nFactLen);
    pHeader->dwPacketLen=htonl(m_buffer.len());
}
void CAvenueSmoothEncoder::SetValue(unsigned short wKey, const string &strValue)
{
    SetValue(wKey,strValue.c_str(),strValue.length());
}
void CAvenueSmoothEncoder::SetValue(unsigned short wKey, unsigned int wValue)
{
    int nNetValue=htonl(wValue);
    SetValue(wKey,&nNetValue,4);
}

void CAvenueSmoothEncoder::BeginValue(unsigned short wType)
{
    if(m_buffer.capacity()<sizeof(SAvenueMsgAttribute))
    {
        m_buffer.add_capacity(SAP_ALIGN(sizeof(SAvenueMsgAttribute)-m_buffer.capacity()));
    }
    SAvenueMsgHeader *pHeader=(SAvenueMsgHeader *)m_buffer.base();
    SAvenueMsgAttribute * pAttri=(SAvenueMsgAttribute *)m_buffer.top();
    pAttri->wType=htons(wType);
    m_buffer.inc_loc(sizeof(SAvenueMsgAttribute));
    pHeader->dwPacketLen=htonl(m_buffer.len());

    pAttriBlock=(unsigned char *)pAttri;
}
void CAvenueSmoothEncoder::AddValueBloc(const void *pData,unsigned int nLen)
{
    unsigned int nFactLen=((nLen&0x03)!=0?((nLen>>2)+1)<<2:nLen);
    if(m_buffer.capacity()<nFactLen)
    {
        m_buffer.add_capacity(SAP_ALIGN(nFactLen-m_buffer.capacity()));
    }
    SAvenueMsgHeader *pHeader=(SAvenueMsgHeader *)m_buffer.base();
    memcpy(m_buffer.top(),pData,nLen);
    memset(m_buffer.top()+nLen,0,nFactLen-nLen);
    m_buffer.inc_loc(nFactLen);
    pHeader->dwPacketLen=htonl(m_buffer.len());
}
void CAvenueSmoothEncoder::EndValue(unsigned short dwLen)
{
    if(dwLen!=0)
        ((SAvenueMsgAttribute *)pAttriBlock)->wLength=htons(dwLen);
    else
        ((SAvenueMsgAttribute *)pAttriBlock)->wLength=htons(m_buffer.top()-pAttriBlock);
}

CAvenueSmoothDecoder::CAvenueSmoothDecoder(const void *pBuffer,int nLen)
{
    m_pBuffer=(void *)pBuffer;
    m_nLen=nLen;
}
CAvenueSmoothDecoder::CAvenueSmoothDecoder()
{
    m_pBuffer=0;
    m_nLen=0;
}
void CAvenueSmoothDecoder::Reset(const void *pBuffer,int nLen)
{
    m_pBuffer=(void *)pBuffer;
    m_nLen=nLen;
}

int CAvenueSmoothDecoder::VerifySignature(const char * szKey, unsigned int nLen)
{
    unsigned char arSignature[16];
    SAvenueMsgHeader *pHeader=(SAvenueMsgHeader *)m_pBuffer;
    memcpy(arSignature,pHeader->bySignature,16);

    int nMin=(nLen<16?nLen:16);
    memset(pHeader->bySignature,0,16);
    memcpy(pHeader->bySignature,szKey,nMin);

    CCipher::Md5((const unsigned char *)m_pBuffer,m_nLen,pHeader->bySignature);
    return memcmp(arSignature,pHeader->bySignature,16);
}

void CAvenueSmoothDecoder::AesDec(unsigned char abyKey[16])
{
    SAvenueMsgHeader *pHeader=(SAvenueMsgHeader *)m_pBuffer;
    unsigned char *ptrLoc=(unsigned char *)m_pBuffer+pHeader->byHeadLen;
    CCipher::AesDec(abyKey,ptrLoc,m_nLen-pHeader->byHeadLen,ptrLoc);
}

void CAvenueSmoothDecoder::GetService(unsigned char * pIdentifer,unsigned int * pServiceId,unsigned int * pMsgId,unsigned int * pdwCode)
{
    SAvenueMsgHeader *pHeader=(SAvenueMsgHeader *)m_pBuffer;
    *pIdentifer=pHeader->byIdentifer;
    *pServiceId=ntohl(pHeader->dwServiceId);
    *pMsgId=ntohl(pHeader->dwMsgId);
    *pdwCode=ntohl(pHeader->dwCode);
}
unsigned char CAvenueSmoothDecoder::GetIdentifier()
{
    SAvenueMsgHeader *pHeader=(SAvenueMsgHeader *)m_pBuffer;
    return pHeader->byIdentifer;
}
unsigned int CAvenueSmoothDecoder::GetServiceId()
{
    SAvenueMsgHeader *pHeader=(SAvenueMsgHeader *)m_pBuffer;
    return ntohl(pHeader->dwServiceId);
}
unsigned int CAvenueSmoothDecoder::GetMsgId()
{
    SAvenueMsgHeader *pHeader=(SAvenueMsgHeader *)m_pBuffer;
    return ntohl(pHeader->dwMsgId);
}
unsigned int CAvenueSmoothDecoder::GetCode()
{
    SAvenueMsgHeader *pHeader=(SAvenueMsgHeader *)m_pBuffer;
    return ntohl(pHeader->dwCode);
}

unsigned int CAvenueSmoothDecoder::GetSequence()
{
    SAvenueMsgHeader *pHeader=(SAvenueMsgHeader *)m_pBuffer;
    return ntohl(pHeader->dwSequence);
}
unsigned int CAvenueSmoothDecoder::GetMsgOption()
{

    SAvenueMsgHeader *pHeader=(SAvenueMsgHeader *)m_pBuffer;
    return *((int *)(&pHeader->byContext));
}
void CAvenueSmoothDecoder::GetExtHeader(void **ppBuffer, int * pLen)
{
    SAvenueMsgHeader *pHeader=(SAvenueMsgHeader *)m_pBuffer;
    *ppBuffer=(unsigned char *)m_pBuffer+sizeof(SAvenueMsgHeader);
    *pLen=pHeader->byHeadLen-sizeof(SAvenueMsgHeader);
}
void CAvenueSmoothDecoder::GetBody(void **ppBuffer, unsigned int * pLen)
{
    SAvenueMsgHeader *pHeader=(SAvenueMsgHeader *)m_pBuffer;;
    *ppBuffer=(unsigned char *)m_pBuffer+pHeader->byHeadLen;
    *pLen=ntohl(pHeader->dwPacketLen)-pHeader->byHeadLen;

}
void CAvenueSmoothDecoder::DecodeBodyAsTLV()
{
    void * pBody;
    unsigned int nBodyLen;
    GetBody(&pBody,&nBodyLen);
    unsigned char *ptrLoc=(unsigned char *)pBody;
    while(ptrLoc<(unsigned char *)pBody+nBodyLen)
    {
        SAvenueMsgAttribute *pAtti=(SAvenueMsgAttribute *)ptrLoc;
        unsigned short nLen=ntohs(pAtti->wLength);
        if(nLen==0)
        {
            break;
        }
        m_mapMultiAttri.insert(AttriMultiMap::value_type(ntohs(pAtti->wType),ptrLoc));
        int nFactLen=((nLen&0x03)!=0?((nLen>>2)+1)<<2:nLen);
        ptrLoc+=nFactLen;
    }
}

int CAvenueSmoothDecoder::GetValue(unsigned short wKey,void** pValue, unsigned int * pValueLen)
{
    AttriMultiMap::const_iterator itr=m_mapMultiAttri.find(wKey);
    if(itr==m_mapMultiAttri.end())
    {
        return -1;
    }

    const unsigned char *ptrLoc=itr->second;
    SAvenueMsgAttribute *pAtti=(SAvenueMsgAttribute *)ptrLoc;
    *pValueLen=ntohs(pAtti->wLength)-sizeof(SAvenueMsgAttribute);
    *pValue=pAtti->acValue;
    return 0;
}
int CAvenueSmoothDecoder::GetValue(unsigned short wKey,string & strValue)
{
    void *pData=NULL;
    unsigned int nLen=0;
    if(GetValue(wKey,&pData,&nLen)==-1||nLen<0)
    {
        return -1;
    }
    strValue=string((const char *)pData,nLen);
    return 0;

}
int CAvenueSmoothDecoder::GetValue(unsigned short wKey, unsigned int * pValue)
{
    void *pData=NULL;
    unsigned int nLen=0;
    if(GetValue(wKey,&pData,&nLen)==-1||nLen!=4)
    {
        return -1;
    }
    *pValue=ntohl(*(int *)pData);
    return 0;
}

void CAvenueSmoothDecoder::GetValues(unsigned short wKey,vector<SAvenueValueNode> &vecValues)
{
    std::pair<AttriMultiMap::const_iterator, AttriMultiMap::const_iterator> itr_pair = m_mapMultiAttri.equal_range(wKey);
    AttriMultiMap::const_iterator itr;
	for(itr=itr_pair.first; itr!=itr_pair.second;itr++)
	{
	    const unsigned char *ptrLoc=itr->second;
        SAvenueMsgAttribute *pAtti=(SAvenueMsgAttribute *)ptrLoc;

        SAvenueValueNode tmp;
        tmp.nLen=ntohs(pAtti->wLength)-sizeof(SAvenueMsgAttribute);
        tmp.pLoc=pAtti->acValue;
		vecValues.push_back(tmp);
	}
}
void CAvenueSmoothDecoder::GetValues(unsigned short wKey,vector<string> &vecValues)
{
    std::pair<AttriMultiMap::const_iterator, AttriMultiMap::const_iterator> itr_pair = m_mapMultiAttri.equal_range(wKey);
    AttriMultiMap::const_iterator itr;
	for(itr=itr_pair.first; itr!=itr_pair.second;itr++)
	{
	    const unsigned char *ptrLoc=itr->second;
        SAvenueMsgAttribute *pAtti=(SAvenueMsgAttribute *)ptrLoc;

        int nLen=ntohs(pAtti->wLength)-sizeof(SAvenueMsgAttribute);
        if(nLen>0)
        {
            string strValue=string((const char *)pAtti->acValue,nLen);
	        vecValues.push_back(strValue);
        }
	}
}
void CAvenueSmoothDecoder::GetValues(unsigned short wKey,vector<unsigned int> &vecValues)
{
    std::pair<AttriMultiMap::const_iterator, AttriMultiMap::const_iterator> itr_pair = m_mapMultiAttri.equal_range(wKey);
    AttriMultiMap::const_iterator itr;
	for(itr=itr_pair.first; itr!=itr_pair.second;itr++)
	{
	    const unsigned char *ptrLoc=itr->second;
        SAvenueMsgAttribute *pAtti=(SAvenueMsgAttribute *)ptrLoc;

        if(ntohs(pAtti->wLength)-sizeof(SAvenueMsgAttribute)==4)
        {
	        vecValues.push_back(ntohl(*(unsigned int *)pAtti->acValue));
        }
	}
}

}
}

max_stars_repo_name: shrewdlin/BPE

max_issues_repo_name: shrewdlin/BPE

max_forks_repo_name: shrewdlin/BPE


text:
#ifndef SHIFT_SERIALIZATION_COMPACT_OUTPUTARCHIVE_HPP
#define SHIFT_SERIALIZATION_COMPACT_OUTPUTARCHIVE_HPP

#include <shift/core/boost_disable_warnings.hpp>
#include <boost/iostreams/filtering_stream.hpp>
#include <shift/core/boost_restore_warnings.hpp>
#include "shift/serialization/compact/compressed.hpp"
#include "shift/serialization/archive.hpp"

namespace shift::serialization
{
template <boost::endian::order Order>
class compact_output_archive final
: public archive<boost::iostreams::filtering_ostream, Order>
{
public:
  using base_t = archive<boost::iostreams::filtering_ostream, Order>;

  /// Constructor.
  compact_output_archive(protocol_version_t protocol_version)
  : archive<boost::iostreams::filtering_ostream, Order>(protocol_version)
  {
  }

  /// Destructor.
  ~compact_output_archive() override = default;

  ///
  compact_output_archive& operator<<(begin_write /*value*/)
  {
    // NOP.
    return *this;
  }

  ///
  compact_output_archive& operator<<(end_write /*value*/)
  {
    // NOP.
    return *this;
  }

  ///
  compact_output_archive& operator<<(begin_field /*value*/)
  {
    // NOP.
    return *this;
  }

  ///
  compact_output_archive& operator<<(end_field /*value*/)
  {
    // NOP.
    return *this;
  }

  ///
  compact_output_archive& operator<<(begin_pair /*value*/)
  {
    // NOP.
    return *this;
  }

  ///
  compact_output_archive& operator<<(end_pair /*value*/)
  {
    // NOP.
    return *this;
  }

  ///
  compact_output_archive& operator<<(begin_tuple /*value*/)
  {
    // NOP.
    return *this;
  }

  ///
  compact_output_archive& operator<<(end_tuple /*value*/)
  {
    // NOP.
    return *this;
  }

  ///
  compact_output_archive& operator<<(begin_array /*value*/)
  {
    // NOP.
    return *this;
  }

  ///
  compact_output_archive& operator<<(end_array /*value*/)
  {
    // NOP.
    return *this;
  }

  ///
  compact_output_archive& operator<<(begin_vector value)
  {
    compressed<std::uint32_t> compressedLength =
      static_cast<std::uint32_t>(value.length);
    BOOST_ASSERT(compressedLength == value.length);
    (*this) << compressedLength;
    return *this;
  }

  ///
  compact_output_archive& operator<<(end_vector /*value*/)
  {
    // NOP.
    return *this;
  }

  ///
  compact_output_archive& operator<<(begin_list value)
  {
    *this << begin_vector{value.length};
    return *this;
  }

  ///
  compact_output_archive& operator<<(end_list /*value*/)
  {
    *this << end_vector{};
    return *this;
  }

  ///
  compact_output_archive& operator<<(begin_set value)
  {
    *this << begin_vector{value.length};
    return *this;
  }

  ///
  compact_output_archive& operator<<(end_set /*value*/)
  {
    *this << end_vector{};
    return *this;
  }

  ///
  compact_output_archive& operator<<(begin_map value)
  {
    *this << begin_vector{value.length};
    return *this;
  }

  ///
  compact_output_archive& operator<<(end_map /*value*/)
  {
    *this << end_vector{};
    return *this;
  }

  ///
  compact_output_archive& operator<<(begin_raw_pointer value)
  {
    (*this) << value.valid;
    return *this;
  }

  ///
  compact_output_archive& operator<<(end_raw_pointer /*value*/)
  {
    // NOP.
    return *this;
  }

  ///
  compact_output_archive& operator<<(begin_shared_pointer value)
  {
    (*this) << value.key;
    return *this;
  }

  ///
  compact_output_archive& operator<<(end_shared_pointer /*value*/)
  {
    // NOP.
    return *this;
  }

  ///
  compact_output_archive& operator<<(bool value)
  {
    write(reinterpret_cast<const char*>(&value), sizeof(value));
    return *this;
  }

  ///
  compact_output_archive& operator<<(char value)
  {
    using namespace boost::endian;
    auto target_value = conditional_reverse<order::native, Order>(value);
    write(reinterpret_cast<const char*>(&target_value), sizeof(value));
    return *this;
  }

  ///
  compact_output_archive& operator<<(char16_t value)
  {
    using namespace boost::endian;
    auto target_value = conditional_reverse<order::native, Order>(value);
    write(reinterpret_cast<const char*>(&target_value), sizeof(target_value));
    return *this;
  }

  ///
  compact_output_archive& operator<<(char32_t value)
  {
    using namespace boost::endian;
    auto target_value = conditional_reverse<order::native, Order>(value);
    write(reinterpret_cast<const char*>(&target_value), sizeof(value));
    return *this;
  }

  ///
  compact_output_archive& operator<<(std::uint8_t value)
  {
    using namespace boost::endian;
    auto target_value = conditional_reverse<order::native, Order>(value);
    write(reinterpret_cast<const char*>(&target_value), sizeof(value));
    return *this;
  }

  ///
  compact_output_archive& operator<<(std::int8_t value)
  {
    using namespace boost::endian;
    auto target_value = conditional_reverse<order::native, Order>(value);
    write(reinterpret_cast<const char*>(&target_value), sizeof(value));
    return *this;
  }

  ///
  compact_output_archive& operator<<(std::uint16_t value)
  {
    using namespace boost::endian;
    auto target_value = conditional_reverse<order::native, Order>(value);
    write(reinterpret_cast<const char*>(&target_value), sizeof(value));
    return *this;
  }

  ///
  compact_output_archive& operator<<(std::int16_t value)
  {
    using namespace boost::endian;
    auto target_value = conditional_reverse<order::native, Order>(value);
    write(reinterpret_cast<const char*>(&target_value), sizeof(value));
    return *this;
  }

  ///
  compact_output_archive& operator<<(std::uint32_t value)
  {
    using namespace boost::endian;
    auto target_value = conditional_reverse<order::native, Order>(value);
    write(reinterpret_cast<const char*>(&target_value), sizeof(value));
    return *this;
  }

  ///
  compact_output_archive& operator<<(std::int32_t value)
  {
    using namespace boost::endian;
    auto target_value = conditional_reverse<order::native, Order>(value);
    write(reinterpret_cast<const char*>(&target_value), sizeof(value));
    return *this;
  }

  ///
  compact_output_archive& operator<<(std::uint64_t value)
  {
    using namespace boost::endian;
    auto target_value = conditional_reverse<order::native, Order>(value);
    write(reinterpret_cast<const char*>(&target_value), sizeof(value));
    return *this;
  }

  ///
  compact_output_archive& operator<<(std::int64_t value)
  {
    using namespace boost::endian;
    auto target_value = conditional_reverse<order::native, Order>(value);
    write(reinterpret_cast<const char*>(&target_value), sizeof(value));
    return *this;
  }

  ///
  compact_output_archive& operator<<(float value)
  {
    using namespace boost::endian;
    auto it = reinterpret_cast<std::byte*>(&value);
    if constexpr (Order != order::native)
      std::reverse(it, it + sizeof(value));
    write(reinterpret_cast<const char*>(it), sizeof(value));
    return *this;
  }

  ///
  compact_output_archive& operator<<(double value)
  {
    using namespace boost::endian;
    auto it = reinterpret_cast<std::byte*>(&value);
    if constexpr (Order != order::native)
      std::reverse(it, it + sizeof(value));
    write(reinterpret_cast<const char*>(it), sizeof(value));
    return *this;
  }

  ///
  compact_output_archive& operator<<(std::string value)
  {
    compressed<std::uint32_t> length = static_cast<uint32_t>(value.size());
    BOOST_ASSERT(length == value.size());
    *this << length;
    write(value.c_str(), length);
    return *this;
  }

public:
  /// Write data to the underlying stream.
  void write(const char* source, std::size_t size)
  {
    base_t::_stream.write(source, size);
  }
};

///
template <typename U, boost::endian::order Order>
compact_output_archive<Order>& operator<<(
  compact_output_archive<Order>& archive, const compressed<U>& value)
{
  auto length = static_cast<U>(value);
  do
  {
    auto digit = static_cast<std::uint8_t>(length & 0x7F);
    if (length > 0x7F)
      digit |= 0x80;
    archive << digit;
    length >>= 7;
  } while (length > 0);
  return archive;
}
}

#endif

max_stars_repo_name: cspanier/shift

max_issues_repo_name: cspanier/shift

max_forks_repo_name: cspanier/shift


text:
#include "A_Star.h"

//#include <queue>
//#include <stdio.h>
//#include <math.h>
//#include <vector>
//#include <cassert>
//#include <typeinfo>
//#include <vector>

#include <boost/math/constants/constants.hpp>
#include <iostream>
#include <vector>

using namespace std;

int A_Star::Get_Shortest_Path(const vector<vector<int>>& array,int Max_Search_Time,bool Debug_Info_Switch){
    //为简单，干脆把把下面数组转为链表结构的数组
    //约定：0是可走的，1表示障碍物不可走，2表示起点，3表示终点
//    vector<vector<int>> array={
//        { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
//        { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0 },
//        { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 },
//        { 0, 0, 0, 0, 1, 1, 0, 0, 0, 0 },
//        { 0, 0, 0, 0, 0, 1, 3, 0, 0, 0 },
//        { 0, 0, 2, 0, 0, 1, 0, 0, 0, 0 },
//        { 0, 0, 0, 0, 1, 1, 0, 0, 0, 0 },
//        { 0, 0, 0, 0, 1, 1, 0, 0, 0, 0 },
//        { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0 },
//        { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } };
    debug_info_switch=Debug_Info_Switch;
    int Error_flag=0;
    bool Input_OK=false;
    Input_OK =Input_Verify(array);
    if(!Input_OK) return Error_flag;
    map.Build_Map(array);

    //PNode *Start_node;
//    Start_node=map.Start_node;
    //PNode *End_node;
//    End_node=map.End_node;

    map.Start_node->G=0;
    map.Start_node->H=H_Calculat(map.Start_node,map.End_node);
    map.Start_node->F=map.Start_node->G+map.Start_node->H;
    map.Start_node->open_flag=1;
    open_List.Heap_push(make_pair(map.Start_node->F,map.Start_node));
//   cout<<"hello world!  "<<Open_List->next->G<<" , "<<Open_List->next->H<<endl;

/********** main search ****************/
    Shortest_Path_Long=-1;
    Count=0;
    int Search_end_flag;
    while(1)
    {
        //cout<<"Count=  "<<Count<<endl;
        Search_end_flag=Search();
        if (Search_end_flag==1)
         {
            if(debug_info_switch)  cout<<" Having find the useable path !!! "<<endl;
            Error_flag=0;
            break;
         }
        if (Count>Max_Search_Time)
         {
            cout<<" Path finding timeout !!! "<<endl;
            Error_flag=1;
            break;
         }
        if (Search_end_flag==2)
         {
            if(debug_info_switch)  cout<<" Can not find the useable path !!! "<<endl;
            Error_flag=1;
            break;
         }

        Count++;
 //       cout<<"opt_node->[G,H]  "<<opt_node->G<<" , "<<opt_node->H<<endl;
    }
    if (Error_flag==0)
    {
        PNode *tmp=map.End_node;
        while(tmp)
        {
            //cout<<" ["<<tmp->x<<" , "<<tmp->y<<"] -> ";
            Shortest_Path.push_back({tmp->x,tmp->y});
            tmp=tmp->path_before;
            Shortest_Path_Long++;
        }
        reverse(Shortest_Path.begin(),Shortest_Path.end());  // " use of undlclared identifier 'reverse' ..."  ----it is why?  need #include <boost/math/constants/constants.hpp>
        //for(size_t i=0;i<Shortest_Path.size()/2;i++){
        //    swap(Shortest_Path[i],Shortest_Path[Shortest_Path.size()-1-i]);
        //}

    }

    //map.Clear_Map();

    return Error_flag;
}

bool A_Star::Input_Verify(const vector<vector<int>>& array){
    int Start_Point_Count=0,End_Point_Count=0;
    for(size_t i=0;i<array.size();i++){
        if(array[i].size() != array[0].size()){
            cout<<" Fatal Wrong , The Input Must be a Mutrix !!! "<<endl;
            return false;
        }
        for(size_t j=0;j<array[i].size();j++){
            if (array[i][j]<0 || array[i][j]>3){
                cout<<" Fatal Wrong , The Value in the Input Mutrix must be 0, 1, 2, 3  !!! "<<endl;
                return false;
            }
            if (array[i][j]==2) Start_Point_Count++;
            if (array[i][j]==3) End_Point_Count++;
        }
    }
    if (Start_Point_Count==1 && End_Point_Count==1) return true;
    else{
        if (Start_Point_Count!=1) cout<<" Fatal Wrong , Cannot find the start point or more than one start point !!! "<<endl;
        if (End_Point_Count!=1) cout<<" Fatal Wrong , Cannot find the end point or more than one end point !!! "<<endl;
        return false;
    }
}

float A_Star::H_Calculat(PNode *cur,PNode *end)
{
    float res=float_abs(cur->x-end->x)+float_abs(cur->y-end->y);
    return res;
}

float A_Star::float_abs(float x){
    return x > 0 ? x:-x;
}

int A_Star::Search()
{
     if (open_List.Heap_size()==0){
         if(debug_info_switch)  cout<<" The Open_List_Min_Heap is empty !!! "<<endl;
         return 2;
     }
     PNode *Opt_node;
     Opt_node=open_List.Heap_top().second;
     Opt_node->open_flag=0;
     Opt_node->close_flag=1;
     open_List.Heap_pop();
    for(size_t i=0;i<Opt_node->adjacent_node.size();i++)
    {
        PNode* Tmp_adjacent_next_node=Opt_node->adjacent_node[i];
        if (Tmp_adjacent_next_node->nodetype==EndPoint)       // End point has been found!!!
        {
            Tmp_adjacent_next_node->path_before=Opt_node;
            return 1;
        }

        if (Tmp_adjacent_next_node->open_flag==0 && Tmp_adjacent_next_node->close_flag==0 && Tmp_adjacent_next_node->nodetype !=UnReachable)
        {
            Tmp_adjacent_next_node->path_before=Opt_node;
            Tmp_adjacent_next_node->G=Opt_node->G+1;
            Tmp_adjacent_next_node->H=H_Calculat(Tmp_adjacent_next_node,map.End_node);
            Tmp_adjacent_next_node->F=Tmp_adjacent_next_node->G+Tmp_adjacent_next_node->H;
            Tmp_adjacent_next_node->open_flag=1;    //The open_flag should be modified! --20200312
            open_List.Heap_push(make_pair(Tmp_adjacent_next_node->F,Tmp_adjacent_next_node));
        }

        else if(Tmp_adjacent_next_node->open_flag==1 && Tmp_adjacent_next_node->close_flag==0)
        {
            float tmp_G=Opt_node->G+1;
            float tmp_H=H_Calculat(Tmp_adjacent_next_node,map.End_node);
            float tmp_F=tmp_G+tmp_H;
            if (tmp_F<Tmp_adjacent_next_node->F){
                //update thr f which is in open list!!!!
                //update thr f which is in open list!!!!
                //update thr f which is in open list!!!!
                Tmp_adjacent_next_node->G=tmp_G;
                Tmp_adjacent_next_node->H=tmp_H;
                Tmp_adjacent_next_node->F=tmp_F;
                Tmp_adjacent_next_node->path_before=Opt_node;
                //open_List.Heap_delect(Tmp_adjacent_next_node);
                //open_List.Heap_push(make_pair(Tmp_adjacent_next_node->F,Tmp_adjacent_next_node));
                open_List.Heap_modify(Tmp_adjacent_next_node,Tmp_adjacent_next_node->F);

            }
            else {
                //no action!
            }

        }
        else if(Tmp_adjacent_next_node->open_flag==0 && Tmp_adjacent_next_node->close_flag==1)
        {
            // no action!
        }
        else if((Tmp_adjacent_next_node->open_flag==0 && Tmp_adjacent_next_node->close_flag==0 && Tmp_adjacent_next_node->nodetype ==UnReachable))
        {
            Tmp_adjacent_next_node->close_flag=1;
        }
        else {
            cout<<"Fatel Error!!!"<<endl;
             return 2;
        }

    }

    return 0;
}

void A_Star::clear(){
    Shortest_Path.clear();
    open_List.Heap_clear();
    map.Clear_Map();
}


text:
#pragma once

#include "terminalpp/core.hpp"
#include "terminalpp/control_sequence.hpp"
#include "terminalpp/mouse.hpp"
#include "terminalpp/virtual_key.hpp"
#include <boost/variant.hpp>
#include <vector>

namespace terminalpp {

using token = boost::variant<
    terminalpp::virtual_key,
    terminalpp::mouse::event,
    terminalpp::control_sequence
>;

using tokens = gsl::span<token const>;
using token_storage = std::vector<token>;

}

max_stars_repo_name: ExternalRepositories/terminalpp

max_issues_repo_name: ExternalRepositories/terminalpp

max_forks_repo_name: ExternalRepositories/terminalpp