text:
#include <bullet/btBulletCollisionCommon.h>
#include <fmt/ostream.h>

#include <Eigen/Core>
#include <Eigen/Geometry>
#include <algorithm>
#include <array>
#include <iostream>
#include <limits>

#include "cspace.hh"

// clang-format off
#include "spdlog/spdlog.h"
#include "spdlog/sinks/stdout_color_sinks.h"
// clang-format on

#include <boost/container_hash/hash.hpp>

#include "fplus/fplus.hpp"

namespace planner::cspace {
namespace {
  auto log                   = spdlog::stdout_color_st("cspace");
  constexpr double neg_infty = -std::numeric_limits<double>::infinity();
  constexpr double pos_infty = std::numeric_limits<double>::infinity();
  constexpr void update_bounds(std::array<double, 3>& min_bounds,
                               std::array<double, 3>& max_bounds,
                               double x,
                               const double y,
                               const double z,
                               const double radius) {
    max_bounds[0] = std::max({x + radius, x - radius, max_bounds[0]});
    min_bounds[0] = std::min({x + radius, x - radius, min_bounds[0]});
    max_bounds[1] = std::max({y + radius, y - radius, max_bounds[1]});
    min_bounds[1] = std::min({y + radius, y - radius, min_bounds[1]});
    max_bounds[2] = std::max({z + radius, z - radius, max_bounds[2]});
    // No need to search for z min as we assume it to be 0
  }
}  // namespace

namespace fwd = fplus::fwd;

std::unique_ptr<ob::RealVectorBounds> workspace_bounds = nullptr;

util::UniverseMap* CompositeSpace::universe_map = nullptr;

// INSANE PLEASE UNDO
void CompositeSpace::sanityChecks(double zero, double eps, unsigned int flags) const {}
void CompositeSpace::sanityChecks() const {}

bool CompositeSpace::isDiscrete() const {
  return std::all_of(components_.begin(), components_.end(), [](const auto& c) {
    return c->isDiscrete();
  });
}

bool CompositeSpace::satisfiesBounds(const ob::State* state) const {
  const auto* cstate = dynamic_cast<const StateType*>(state);
  for (unsigned int i = 0; i < componentCount_; ++i) {
    const auto& component = getSubspace(i);
    if (!component->satisfiesBounds(cstate->components[i])) {
      log->debug("State failed to satisfy bounds for subspace {}.", component->getName());
      return false;
    }
  }

  return true;
}

void CompositeSpace::interpolate(const ob::State* from,
                                 const ob::State* to,
                                 const double t,
                                 ob::State* state) const {
  // We only interpolate in robot state, then update object poses accordingly
  const auto* cfrom = static_cast<const StateType*>(from);
  const auto* cto   = static_cast<const StateType*>(to);
  auto* cstate      = static_cast<StateType*>(state);

  // Set object_poses pointer to be the pose set from the origin
  cstate->object_poses = cfrom->object_poses;
  cstate->sg           = cfrom->sg;

  // Null the action pointer since by interpolating we effectively didn't take an action to get
  // here
  cstate->action = nullptr;

  // Interpolate the robot state
  getSubspace(robot_space_idx)
  ->interpolate(cfrom->components[robot_space_idx],
                cto->components[robot_space_idx],
                t,
                cstate->components[robot_space_idx]);

  // Copy the object state
  getSubspace(objects_space_idx)
  ->copyState(cstate->components[objects_space_idx], cfrom->components[objects_space_idx]);

  // Copy the discrete state
  getSubspace(eqclass_space_idx)
  ->copyState(cstate->components[eqclass_space_idx], cfrom->components[eqclass_space_idx]);

  getSubspace(discrete_space_idx)
  ->copyState(cstate->components[discrete_space_idx], cfrom->components[discrete_space_idx]);

  // Update object poses according to the interpolated robot state
  auto* objects_state       = cstate->as<ob::CompoundState>(objects_space_idx);
  const auto* objects_space = components_[objects_space_idx]->as<ob::CompoundStateSpace>();
  const auto poser          = [&](const structures::scenegraph::Node* const node,
                         const bool robot_ancestor,
                         const Transform3r& tf,
                         const Transform3r& _) {
    if (robot_ancestor && node->is_object) {
      auto object_state =
      objects_state->as<ObjectSpace::StateType>(objects_space->getSubspaceIndex(node->name));
      const auto& translation = tf.translation();
      Eigen::Quaterniond rotation(tf.linear());
      // rotation.normalize();
      object_state->setXYZ(translation.x(), translation.y(), translation.z());
      auto& object_rotation = object_state->rotation();
      object_rotation.x     = rotation.x();
      object_rotation.y     = rotation.y();
      object_rotation.z     = rotation.z();
      object_rotation.w     = rotation.w();
    }
  };

  const auto* robot_state = cstate->as<ob::CompoundState>(robot_space_idx);
  double cont_vals[cont_joint_idxs.size()];
  double* joint_vals      = nullptr;
  const auto& joint_state = robot_state->as<cspace::RobotJointSpace::StateType>(joint_space_idx);
  Transform3r base_tf;
  util::state_to_pose_data(robot_state,
                           joint_state,
                           cspace::cont_joint_idxs,
                           base_space_idx,
                           cont_vals,
                           &joint_vals,
                           &base_tf);

  cstate->sg->update_transforms(cont_vals, joint_vals, base_tf, poser);
}

double CompositeSpace::distance(const ob::State* state1, const ob::State* state2) const {
  const auto* cstate1         = static_cast<const StateType*>(state1);
  const auto* cstate2         = static_cast<const StateType*>(state2);
  const bool same_object_pose = cstate1->object_poses == cstate2->object_poses;
  // const auto* eqclass_space   = components_[eqclass_space_idx].get();
  // const auto* discrete_space  = components_[discrete_space_idx].get();
  // const bool same_universe =
  // eqclass_space->equalStates(cstate1->as<DiscreteSpace::StateType>(eqclass_space_idx),
  //                            cstate2->as<DiscreteSpace::StateType>(eqclass_space_idx));
  // const bool same_config =
  // discrete_space->equalStates(cstate1->as<DiscreteSpace::StateType>(discrete_space_idx),
  //                             cstate2->as<DiscreteSpace::StateType>(discrete_space_idx));
  // const bool same_discrete = same_universe && same_config;
  if (true && universe_map->check_valid_transition(cstate1, cstate2)) {
    return contDistance(state1, state2);
  }

  return pos_infty;
}

double CompositeSpace::contDistance(const ob::State* state1, const ob::State* state2) const {
  const auto* cstate1 = static_cast<const StateType*>(state1);
  const auto* cstate2 = static_cast<const StateType*>(state2);
  double dist         = 0.0;
  for (unsigned int i = 0; i < componentCount_; ++i) {
    if (i != eqclass_space_idx && i != discrete_space_idx) {
      dist +=
      weights_[i] * components_[i]->distance(cstate1->components[i], cstate2->components[i]);
    }
  }

  return dist;
}

size_t CompositeSpace::computeHash(const StateType& x) const {
  size_t hash_val = 0;
  // We have to do this component-by-component because not all subspaces (i.e. CompoundStateSpace
  // and RealVectorStateSpace) have hash implementations b/c of the stupid OMPL lack of length
  // information

  // Robot subspace
  const auto& robot_state = x.as<ob::CompoundState>(robot_space_idx);
  const auto& robot_space = components_[robot_space_idx]->as<ob::CompoundStateSpace>();
  // Robot: Base subspace (if exists)
  if (robot_space->hasSubspace(BASE_SPACE)) {
    const auto& base_state =
    robot_state->as<RobotBaseSpace::StateType>(robot_space->getSubspaceIndex(BASE_SPACE));
    boost::hash_combine(hash_val, *base_state);
  }

  // Robot: Continuous joints subspaces
  for (const auto idx : cont_joint_idxs) {
    const auto& joint_state = robot_state->as<ob::SO2StateSpace::StateType>(idx);
    boost::hash_combine(hash_val, *joint_state);
  }

  // Robot: Other joints subspaces
  const auto joint_space_idx = robot_space->getSubspaceIndex(JOINT_SPACE);
  const auto& joints_state   = robot_state->as<RobotJointSpace::StateType>(joint_space_idx);
  for (unsigned int i = 0; i < joint_bounds.size(); ++i) {
    boost::hash_combine(hash_val, joints_state->values[i]);
  }

  // Objects subspace
  const auto& objects_state = x.as<ob::CompoundState>(objects_space_idx);
  for (unsigned int i = 0; i < num_objects; ++i) {
    boost::hash_combine(hash_val, *(objects_state->as<ObjectSpace::StateType>(i)));
  }

  // Universe subspace
  const auto& universe_state = x.as<ob::CompoundState>(eqclass_space_idx);
  for (unsigned int i = 0; i < eqclass_subspace_count; ++i) {
    boost::hash_combine(hash_val, *(universe_state->as<DiscreteSpace::StateType>(i)));
  }

  // Config subspace
  const auto& config_state = x.as<ob::CompoundState>(discrete_space_idx);
  for (unsigned int i = 0; i < discrete_subspace_count; ++i) {
    boost::hash_combine(hash_val, *(config_state->as<DiscreteSpace::StateType>(i)));
  }

  return hash_val;
}

// NOTE: Spooky scary global state
int num_dims = 0;
Vec<int> cont_joint_idxs;
Vec<std::pair<double, double>> joint_bounds;

std::tuple<std::array<double, 3>, std::array<double, 3>, double>
make_workspace_bounds(const structures::robot::Robot& robot,
                      structures::scenegraph::Graph* const sg,
                      const structures::object::ObjectSet& objects,
                      const structures::object::ObjectSet& obstacles) {
  // Compute a bounding box for the workspace by (a) finding the min and max (x, y, z) of the
  // robot and all objects (including bounding boxes) and (b) adding 2 * robot diameter to each
  // to allow room to move around the workspace
  std::array<double, 3> max_bounds{neg_infty, neg_infty, neg_infty};
  std::array<double, 3> min_bounds{pos_infty, pos_infty, 0.0};

  // Handle the robot
  double robot_radius              = 0.0;
  const Vector3r& base_translation = robot.base_pose->translation();
  double radius, x, y, z;
  auto robot_walker =
  [&](const auto* const node, const bool robot_ancestor, const auto& tf, const auto& coll_tf) {
    // Ignore non-robot nodes
    if (node->is_object || node->is_obstacle) {
      return;
    }

    // We overapproximate each collision geometry as a sphere
    if (node->geom != nullptr) {
      btScalar bRadius;
      btVector3 bCenter;
      node->geom->getBoundingSphere(bCenter, bRadius);
      radius = bRadius;
    }

    const Eigen::Vector3d& translation = coll_tf.translation();

    // Update current limits
    update_bounds(min_bounds, max_bounds, translation[0], translation[1], translation[2], radius);

    // Update robot diameter
    const auto position_vector = translation - base_translation;
    const auto furthest_point  = position_vector.norm() + radius;
    if (furthest_point > robot_radius) {
      robot_radius = furthest_point;
    }
  };

  const Transform3r base_tf(*robot.base_pose);
  sg->update_transforms<double>(nullptr, nullptr, base_tf, robot_walker);

  // Now that we have the "correct" robot radius, check for bounds updates
  update_bounds(min_bounds,
                max_bounds,
                base_translation[0],
                base_translation[1],
                base_translation[2],
                robot_radius);
  log->info("Robot radius: {}", robot_radius);

  // Handle the objects
  for (const auto& object : fplus::get_map_values(objects)) {
    object->get_bounding_sphere(x, y, z, radius);
    log->info("Bounds for {} are ({}, {}, {}) with radius {}", object->name, x, y, z, radius);
    update_bounds(min_bounds, max_bounds, x, y, z, radius);
  }

  // Handle the obstacles
  for (const auto& obstacle : fplus::get_map_values(obstacles)) {
    obstacle->get_bounding_sphere(x, y, z, radius);
    log->info("Bounds for {} are ({}, {}, {}) with radius {}", obstacle->name, x, y, z, radius);
    update_bounds(min_bounds, max_bounds, x, y, z, radius);
  }

  return std::make_tuple(std::move(min_bounds), std::move(max_bounds), robot_radius);
}

std::shared_ptr<ob::CompoundStateSpace> make_robot_cspace(const structures::robot::Robot& robot) {
  /// Make the robot's configuration space based on its joints and the mobility of its base
  auto robot_space = std::make_shared<ob::CompoundStateSpace>();
  robot_space->setName(ROBOT_SPACE);

  // Make the joint subspace(s)
  auto joint_space = std::make_shared<RobotJointSpace>();
  joint_space->setName(JOINT_SPACE);
  int idx = 0;
  for (const auto& joint_data : robot.controllable_joints) {
    const auto& [joint_name, lower, upper, _] = joint_data.second;
    if (lower == upper) {
      log->debug("Joint {} has zero-measure bounds; assuming fixed and not adding", joint_name);
      continue;
    }

    // NOTE: The below comparison is OK because f == f for all floating point f, and we're
    // getting the same representation here both times
    if (robot.tree_nodes.at(joint_name)->type == structures::scenegraph::Node::Type::CONTINUOUS) {
      log->debug("Joint {} is continuous. Adding SO(2) subspace!", joint_name);
      auto cont_joint_subspace = std::make_shared<ob::SO2StateSpace>();
      cont_joint_subspace->setName(joint_name);
      robot_space->addSubspace(cont_joint_subspace, 1.0);
      const auto joint_idx                 = robot_space->getSubspaceIndex(joint_name);
      robot.tree_nodes.at(joint_name)->idx = joint_idx;
      cont_joint_idxs.push_back(joint_idx);
      num_dims += 1;
    } else {
      log->debug("Added dimension for joint {} bounded by ({}, {})", joint_name, lower, upper);
      joint_space->addDimension(joint_name, lower, upper);
      // This tracks the index of this controllable joint in the robot state vector
      robot.tree_nodes.at(joint_name)->idx = idx;
      ++idx;
      joint_bounds.push_back({lower, upper});
    }
  }

  // TODO(Wil): Should probably add a dimension for the torso if one exists

  // Add SE(3) for the robot base if it's movable
  if (robot.base_movable) {
    auto base_space = std::make_shared<RobotBaseSpace>();
    base_space->setName(BASE_SPACE);
    // Note: We restrict the Z coordinate of the base pose to its initial value
    auto base_bounds = *workspace_bounds;
    base_bounds.setLow(2, robot.base_pose->translation().z());
    base_bounds.setHigh(2, robot.base_pose->translation().z());
    base_space->setBounds(base_bounds);
    robot_space->addSubspace(base_space, 1.0);
    log->debug("Added (x, y, z, rot) for base mobility");
    // NOTE: Base pose is stored as (x, y, z, rot) right now; we'd need to update to full SE(3) to
    // plan with non ground-based robots
    // We represent the base pose copy with (x, y, z, rotation)
    num_dims += 4;
  }

  // Add in the joint subspace
  robot_space->addSubspace(joint_space, 1.0);
  num_dims += joint_space->getDimension();
  const auto& bounds = joint_space->getBounds();
  for (unsigned int i = 0; i < joint_space->getDimension(); ++i) {
    const auto& name = joint_space->getDimensionName(i);
    log->debug("Robot dimension '{}' at index {} has bounds [{}, {}]",
               name,
               i,
               bounds.low[i],
               bounds.high[i]);
  }

  return robot_space;
}

std::shared_ptr<ob::CompoundStateSpace>
make_object_cspace(const structures::object::ObjectSet& objects) {
  /// Make a configuration space with a copy of SE(3) for each movable object
  // NOTE: I hack on a pad on the workspace bounds for the object subspaces to account for posing
  ob::RealVectorBounds object_bounds(*workspace_bounds);
  object_bounds.low[0] -= 0.3;
  object_bounds.low[1] -= 0.3;
  object_bounds.low[2] -= 0.3;
  object_bounds.high[0] += 0.3;
  object_bounds.high[1] += 0.3;
  object_bounds.high[2] += 0.3;
  auto object_space = std::make_shared<ob::CompoundStateSpace>();
  object_space->setName(OBJECT_SPACE);
  log->debug("Adding {} copies of SE(3) for movable objects", objects.size());
  for (const auto& [obj_name, _] : objects) {
    log->debug("Making SE(3) copy for {}", obj_name);
    auto obj = std::make_shared<ObjectSpace>();
    obj->setName(obj_name);
    obj->setBounds(object_bounds);
    object_space->addSubspace(obj, 1.0);
  }

  return object_space;
}

std::shared_ptr<ob::CompoundStateSpace>
make_eqclass_cspace(const input::specification::Domain& domain) {
  /// Make discrete dimensions for each discrete dimension that can modify the "valid sample"
  /// space for a universe; i.e. the set of equivalence class identifying dimensions
  auto eqclass_space = std::make_shared<ob::CompoundStateSpace>();
  eqclass_space->setName(EQCLASS_SPACE);
  if (domain.eqclass_dimension_ids.empty()) {
    log->critical("No kinematic predicates found! This will probably cause a crash, and you're "
                  "probably using the wrong tool...");
  } else {
    for (const auto& [dim_name, dim_idx] : fwd::apply(domain.eqclass_dimension_ids,
                                                      fwd::map_to_pairs(),
                                                      fwd::sort_by([](const auto&a, const auto&b) {
                                                        return a.second < b.second;
                                                      }))) {
      log->debug("Making eqclass dimension for {}", dim_name);
      auto disc_space = std::make_shared<DiscreteSpace>(0, 1);
      disc_space->setName(dim_name);
      eqclass_space->addSubspace(disc_space, 1.0);
      if (eqclass_space->getSubspaceIndex(dim_name) != dim_idx) {
        log->warn("Subspace index for {} isn't what was expected: {} vs {}",
                  dim_name,
                  eqclass_space->getSubspaceIndex(dim_name),
                  dim_idx);
      }
    }
  }

  return eqclass_space;
}

std::shared_ptr<ob::CompoundStateSpace>
make_discrete_cspace(const input::specification::Domain& domain) {
  auto discrete_space = std::make_shared<ob::CompoundStateSpace>();
  discrete_space->setName(DISCRETE_SPACE);
  if (domain.discrete_dimension_ids.empty()) {
    log->error("No discrete predicates found! This is weird, and will probably cause a crash");
  } else {
    for (const auto& [dim_name, dim_idx] : fwd::apply(domain.discrete_dimension_ids,
                                                      fwd::map_to_pairs(),
                                                      fwd::sort_by([](const auto&a, const auto&b) {
                                                        return a.second < b.second;
                                                      }))) {
      log->debug("Making discrete dimension for {}", dim_name);
      auto disc_space = std::make_shared<DiscreteSpace>(0, 1);
      disc_space->setName(dim_name);
      discrete_space->addSubspace(disc_space, 1.0);
      if (discrete_space->getSubspaceIndex(dim_name) != dim_idx) {
        log->warn("Subspace index for {} isn't what was expected: {} vs {}",
                  dim_name,
                  discrete_space->getSubspaceIndex(dim_name),
                  dim_idx);
      }
    }
  }

  return discrete_space;
}

std::tuple<std::shared_ptr<CompositeSpace>,
           std::shared_ptr<ob::CompoundStateSpace>,
           std::shared_ptr<ob::CompoundStateSpace>,
           std::shared_ptr<ob::CompoundStateSpace>,
           std::shared_ptr<ob::CompoundStateSpace>>
make_cspace(const structures::robot::Robot& robot,
            structures::scenegraph::Graph* const sg,
            const input::specification::Domain& domain,
            const structures::object::ObjectSet& objects,
            const structures::object::ObjectSet& obstacles,
            const std::optional<std::array<structures::object::Bounds, 3>>& known_bounds) {
  /// Call the various configuration space generating functions to make the overall compound
  /// space
  auto cspace = std::make_shared<CompositeSpace>();

  workspace_bounds = std::make_unique<ob::RealVectorBounds>(3);
  if (known_bounds) {
    const auto& x_bounds = known_bounds->at(0);
    const auto& y_bounds = known_bounds->at(1);
    const auto& z_bounds = known_bounds->at(2);

    workspace_bounds->setLow(0, x_bounds.low);
    workspace_bounds->setHigh(0, x_bounds.high);

    workspace_bounds->setLow(1, y_bounds.low);
    workspace_bounds->setHigh(1, y_bounds.high);

    workspace_bounds->setLow(2, z_bounds.low);
    workspace_bounds->setHigh(2, z_bounds.high);
  } else {
    const auto& [min_bounds, max_bounds, robot_radius] =
    make_workspace_bounds(robot, sg, objects, obstacles);
    for (int i = 0; i < 2; ++i) {
      workspace_bounds->setLow(i, min_bounds[i] - robot_radius);
      workspace_bounds->setHigh(i, max_bounds[i] + robot_radius);
    }
    workspace_bounds->setHigh(2, max_bounds[2] + robot_radius);
    workspace_bounds->setLow(2, 0.0);
  }

  auto robot_space = make_robot_cspace(robot);
  cspace->addSubspace(robot_space, 1.0);
  cspace->robot_space_idx = cspace->getSubspaceIndex(ROBOT_SPACE);
  if (robot.base_movable) {
    cspace->base_space_idx = robot_space->getSubspaceIndex(BASE_SPACE);
  } else {
    cspace->base_space_idx = -1;
  }

  cspace->joint_space_idx = robot_space->getSubspaceIndex(JOINT_SPACE);
  cspace->base_movable    = robot.base_movable;

  auto objects_space = make_object_cspace(objects);
  cspace->addSubspace(objects_space, 1.0);
  cspace->objects_space_idx = cspace->getSubspaceIndex(OBJECT_SPACE);
  cspace->num_objects       = objects_space->getSubspaceCount();

  log->info("Workspace bounds are:\n\tlow: {}\n\thigh: {}",
            workspace_bounds->low,
            workspace_bounds->high);

  auto universe_space = make_eqclass_cspace(domain);
  cspace->addSubspace(universe_space, 1.0);
  cspace->eqclass_space_idx      = cspace->getSubspaceIndex(EQCLASS_SPACE);
  cspace->eqclass_subspace_count = universe_space->getSubspaceCount();

  auto discrete_space = make_discrete_cspace(domain);
  cspace->addSubspace(discrete_space, 1.0);
  cspace->discrete_space_idx      = cspace->getSubspaceIndex(DISCRETE_SPACE);
  cspace->discrete_subspace_count = discrete_space->getSubspaceCount();

  return std::make_tuple(std::move(cspace),
                         std::move(robot_space),
                         std::move(objects_space),
                         std::move(universe_space),
                         std::move(discrete_space));
}
}  // namespace planner::cspace

max_stars_repo_name: MiaoDragon/planet

max_issues_repo_name: MiaoDragon/planet

max_forks_repo_name: MiaoDragon/planet


text:
#ifndef COMPONENTPROXY_HPP_
#define COMPONENTPROXY_HPP_

#include <string>
#include <map>
#include <vector>

#include <boost/foreach.hpp>

namespace DisCODe {

class Client;

class ComponentProxy {
public:
	ComponentProxy(Client * client, const std::string & name);

	void refresh();

	void print(int indent = 0);

	int countHandlers() const {
		return handlers.size();
	}

	std::string getHandler(int i) {
		return handlers[i];
	}

	void triggerHandler(int i);
	void triggerHandler(const std::string & handler);

	int countProperties() const {
		return properties.size();
	}

	std::string getPropertyName(int i) {
		return properties[i];
	}

	std::string getPropertyValue(int i);
	std::string setPropertyValue(int i, const std::string & val);
	std::string setPropertyValue(const std::string & name, const std::string & val);

	std::string getPropertyType(int i);
	std::string getPropertyToolTip(int i);

	std::vector<std::string> getPropertyConstraints(int i) {
		return constraints[i];
	}

	std::string name() const {
		return m_name;
	}

	int getBump() const {
		return m_bump;
	}

	void setBump(int bump);

	int getPriority() const {
		return m_priority;
	}

	const std::string& getType() const {
		return m_type;
	}

private:
	Client * m_client;

	std::string m_name;

	//typedef std::pair<std::string, std::string> PropertyPair;

	//std::map<std::string, std::string> properties;

	std::vector<std::string> properties;

	std::vector<std::string> handlers;

	void refreshPropertyConstraints(int i);

	std::vector<std::vector<std::string> > constraints;

	std::string m_type;

	int m_priority;
	int m_bump;
};

}

#endif /* COMPONENTPROXY_HPP_ */

ext: hpp

max_stars_repo_name: mlaszko/DisCODe

max_issues_repo_name: mlaszko/DisCODe

max_forks_repo_name: mlaszko/DisCODe


text:
// Boost.Range 2.0 Extension library
// via PStade Oven Library
//
// Copyright Kohei Takahashi 2014.
// Copyright Akira Takahashi 2011.
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
//[outdirected_example
#include <boost/range/adaptor/outdirected.hpp>
#include <boost/range/adaptor/indirected.hpp>
#include <boost/range/algorithm/sort.hpp>
#include <boost/range/algorithm/copy.hpp>
#include <boost/assign.hpp>
#include <iterator>
#include <vector>
#include <iostream>

struct indirect_less
{
    template <typename I>
    bool operator()( I l, I r ) const { return *l < *r; }
};

int main()
{
    using namespace boost::assign;
    using namespace boost::adaptors;

    std::vector<int> input;
    input += 3,1,4,2,5;

    std::vector<std::vector<int>::const_iterator> iinput;
    boost::copy(
        input | outdirected,
        std::back_inserter(iinput));
    boost::sort(iinput, indirect_less());

    boost::copy(
        iinput | indirected,
        std::ostream_iterator<int>(std::cout, " "));
    std::cout << std::endl;
    boost::copy(
        input,
        std::ostream_iterator<int>(std::cout, " "));
}
//]

/*
output:
1 2 3 4 5
3 1 4 2 5
*/

ext: cpp

max_stars_repo_name: Flast/OvenToBoost

max_issues_repo_name: Flast/OvenToBoost

max_forks_repo_name: Flast/OvenToBoost


text:
/**
 * @file dex.cpp
 *
 * This file contains DEx logic.
 */

#include <tradelayer/dex.h>

#include <tradelayer/convert.h>
#include <tradelayer/errors.h>
#include <tradelayer/externfns.h>
#include <tradelayer/log.h>
#include <tradelayer/mdex.h>
#include <tradelayer/rules.h>
#include <tradelayer/sp.h>
#include <tradelayer/tradelayer.h>
#include <tradelayer/uint256_extensions.h>

#include <arith_uint256.h>
#include <hash.h>
#include <tinyformat.h>
#include <uint256.h>

#include <stdint.h>
#include <fstream>
#include <map>
#include <set>
#include <string>
#include <utility>
#include <vector>

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

std::map<int, std::map<uint32_t,int64_t>> mastercore::MapLTCVolume;
std::map<int, std::map<uint32_t,int64_t>> mastercore::MapTokenVolume;
std::map<uint32_t,std::map<int,std::vector<std::pair<int64_t,int64_t>>>> mastercore::tokenvwap;

namespace mastercore
{

extern CMPSPInfo *_my_sps;
/**
 * Checks, if such a sell offer exists.
 */
bool DEx_offerExists(const std::string& addressSeller, uint32_t propertyId)
{
    std::string key = STR_SELLOFFER_ADDR_PROP_COMBO(addressSeller, propertyId);

    return !(my_offers.find(key) == my_offers.end());
}

/**
 * Retrieves a sell offer.
 *
 * @return The sell offer, or NULL, if no match was found
 */
CMPOffer* DEx_getOffer(const std::string& addressSeller, uint32_t propertyId)
{
    if (msc_debug_dex) PrintToLog("%s(%s, %d)\n", __func__, addressSeller, propertyId);

    std::string key = STR_SELLOFFER_ADDR_PROP_COMBO(addressSeller, propertyId);
    OfferMap::iterator it = my_offers.find(key);

    if (it != my_offers.end()) return &(it->second);

    return static_cast<CMPOffer*>(nullptr);
}

/**
 * Checks, if such an accept order exists.
 */
bool DEx_acceptExists(const std::string& addressSeller, uint32_t propertyId, const std::string& addressBuyer)
{
    std::string key = STR_ACCEPT_ADDR_PROP_ADDR_COMBO(addressSeller, addressBuyer, propertyId);

    return !(my_accepts.find(key) == my_accepts.end());
}

/**
 * Retrieves an accept order.
 *
 * @return The accept order, or NULL, if no match was found
 */
CMPAccept* DEx_getAccept(const std::string& addressSeller, uint32_t propertyId, const std::string& addressBuyer)
{
    if (msc_debug_dex) PrintToLog("%s(%s, %d, %s)\n", __func__, addressSeller, propertyId, addressBuyer);

    std::string key = STR_ACCEPT_ADDR_PROP_ADDR_COMBO(addressSeller, addressBuyer, propertyId);
    AcceptMap::iterator it = my_accepts.find(key);

    if (it != my_accepts.end()) {
      if (msc_debug_dex) PrintToLog("%s(): ORDER FOUND!, getAcceptBlock : %d\n",__func__, (it->second).getAcceptBlock());
      return &(it->second);
    }

    if (msc_debug_dex) PrintToLog("%s(): accept order not found!\n",__func__);

    return static_cast<CMPAccept*>(nullptr);
}

/**
 * Determines the amount of litecoins desired, in case it needs to be recalculated.
 *
 * TODO: don't expose it!
 * @return The amount of litecoins desired
 */
int64_t calculateDesiredLTC(const int64_t amountOffered, const int64_t amountDesired, const int64_t amountAvailable)
{
    if (amountOffered == 0) {
        return 0; // divide by null protection
    }

    arith_uint256 amountOffered256 = ConvertTo256(amountOffered);
    arith_uint256 amountDesired256 = ConvertTo256(amountDesired);
    arith_uint256 amountAvailable256 = ConvertTo256(amountAvailable);

    amountDesired256 = DivideAndRoundUp((amountDesired256 * amountAvailable256), amountOffered256);

    return ConvertTo64(amountDesired256);
}

/**
 * Creates a new sell offer.
 *
 * @return 0 if everything is OK
 */
int DEx_offerCreate(const std::string& addressSeller, uint32_t propertyId, int64_t amountOffered, int block, int64_t amountDesired, int64_t minAcceptFee, uint8_t paymentWindow, const uint256& txid, uint64_t* nAmended)
{
    int rc = DEX_ERROR_SELLOFFER;

    // sanity checks
    // shold not be removed, because it may be used when updating/destroying an offer
    if (paymentWindow == 0) {
        return (DEX_ERROR_SELLOFFER -101);
    }
    if (amountDesired == 0) {
        return (DEX_ERROR_SELLOFFER -102);
    }

    if (propertyId == TL_PROPERTY_VESTING) {
        return (DEX_ERROR_SELLOFFER -103);
    }

    if (DEx_getOffer(addressSeller, propertyId)) {
        return (DEX_ERROR_SELLOFFER -10); // offer already exists
    }

    const std::string key = STR_SELLOFFER_ADDR_PROP_COMBO(addressSeller, propertyId);
    if (msc_debug_dex) PrintToLog("%s(%s|%s), nValue=%d)\n", __func__, addressSeller, key, amountOffered);

    const int64_t balanceReallyAvailable = getMPbalance(addressSeller, propertyId, BALANCE);

    if (amountOffered > balanceReallyAvailable) {
        PrintToLog("%s: rejected: sender %s has insufficient balance of property %d [%s < %s]\n", __func__,
                        addressSeller, propertyId, FormatDivisibleMP(balanceReallyAvailable), FormatDivisibleMP(amountOffered));
        return (DEX_ERROR_SELLOFFER -25);
      }

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

    if (amountOffered > 0) {
        assert(update_tally_map(addressSeller, propertyId, -amountOffered, BALANCE));
        assert(update_tally_map(addressSeller, propertyId, amountOffered, SELLOFFER_RESERVE));
        CMPOffer sellOffer(block, amountOffered, propertyId, amountDesired, minAcceptFee, paymentWindow, txid,0, 2);
        my_offers.insert(std::make_pair(key, sellOffer));

        rc = 0;
    }

    return rc;
}

int DEx_BuyOfferCreate(const std::string& addressMaker, uint32_t propertyId, int64_t amountOffered, int block, int64_t price, int64_t minAcceptFee, uint8_t paymentWindow, const uint256& txid, uint64_t* nAmended)
{
    // bool ready = false;
    int rc = DEX_ERROR_SELLOFFER;

    // sanity checks
    if (paymentWindow == 0)
    {
        if (msc_debug_dex) PrintToLog("DEX_ERROR_SELLOFFER\n");
        return (DEX_ERROR_SELLOFFER -101);
    }

    if (price == 0)
    {
        if (msc_debug_dex) PrintToLog("DEX_ERROR_SELLOFFER\n");
        return (DEX_ERROR_SELLOFFER -101);
    }

    if (DEx_getOffer(addressMaker, propertyId))
    {
        if (msc_debug_dex) PrintToLog("DEX_ERROR_SELLOFFER\n");
        return (DEX_ERROR_SELLOFFER -10); // offer already exists
    }

    const std::string key = STR_SELLOFFER_ADDR_PROP_COMBO(addressMaker, propertyId);
    if (msc_debug_dex) PrintToLog("%s(%s|%s), nValue=%d)\n", __func__, addressMaker, key, amountOffered);

    // ------------------------------------------------------------------------
    // On this part we need to put in reserve synth Litecoins.
    LOCK(cs_tally);

    arith_uint256 sumValues;
    uint32_t nextSPID = _my_sps->peekNextSPID();

    for (uint32_t propertyId = 1; propertyId < nextSPID; propertyId++)
    {
        CMPSPInfo::Entry sp;
        if (_my_sps->getSP(propertyId, sp))
        {
            if (msc_debug_dex) PrintToLog("Property Id: %d\n",propertyId);
            if (!sp.isContract())
	              continue;

            int64_t longs = 0;
            int64_t shorts = 0;

            const int64_t balance = getMPbalance(addressMaker, propertyId, CONTRACT_BALANCE);

            (balance > 0) ? longs = balance : shorts = balance;

            if (msc_debug_dex) PrintToLog("%s(): longs: %d, shorts: %d, notional: %d\n",__func__, longs, shorts, sp.notional_size);

            // price of one sLTC in ALLs
            int64_t pair = getPairMarketPrice("sLTC", "ALL");

            if (msc_debug_dex) PrintToLog("pair: %d\n", pair);

            const int64_t side = (longs >= 0 && shorts == 0) ? longs : (longs == 0 && shorts >= 0) ? shorts : 0;
            arith_uint256 sumNum = (ConvertTo256(side) * ConvertTo256(sp.notional_size)) * ConvertTo256(pair);
            sumValues += DivideAndRoundUp(sumNum, COIN);
	          if (sumValues > ConvertTo256(price))
            {
                // price = price of entire order   .
	              if (msc_debug_dex) PrintToLog("You can buy tokens now\n");
	              // ready = true;
	              break;
            }
        }
    }

    // NOTE: check conditions to buy tokens using litecoin
    // if (ready)
    if (true)
    {
        CMPOffer sellOffer(block, amountOffered, propertyId, price, minAcceptFee, paymentWindow, txid, 0, 1);
        my_offers.insert(std::make_pair(key, sellOffer));
        rc = 0;
    } else {
        if (msc_debug_dex) PrintToLog("You can't buy tokens, you need more position value\n");
        rc = -1;
    }

    return rc;
}

/**
 * Destroys a sell offer.
 *
 * The remaining amount reserved for the offer is returned to the available balance.
 *
 * @return 0 if the offer was destroyed
 */
int DEx_offerDestroy(const std::string& addressSeller, uint32_t propertyId)
{
    if (!DEx_offerExists(addressSeller, propertyId)) {
        return (DEX_ERROR_SELLOFFER -11); // offer does not exist
    }

    const int64_t amountReserved = getMPbalance(addressSeller, propertyId, SELLOFFER_RESERVE);

    // return the remaining reserved amount back to the seller
    if (amountReserved > 0) {
        assert(update_tally_map(addressSeller, propertyId, -amountReserved, SELLOFFER_RESERVE));
        assert(update_tally_map(addressSeller, propertyId, amountReserved, BALANCE));
    }

    // delete the offer
    const std::string key = STR_SELLOFFER_ADDR_PROP_COMBO(addressSeller, propertyId);
    OfferMap::iterator it = my_offers.find(key);
    if (it != my_offers.end()) my_offers.erase(it);

    if (msc_debug_dex) PrintToLog("%s(%s|%s)\n", __func__, addressSeller, key);

    return 0;
}

/**
 * Updates a sell offer.
 *
 * The old offer is destroyed, and replaced by the updated offer.
 *
 * @return 0 if everything is OK
 */
int DEx_offerUpdate(const std::string& addressSeller, uint32_t propertyId, int64_t amountOffered, int block, int64_t amountDesired, int64_t minAcceptFee, uint8_t paymentWindow, const uint256& txid, uint64_t* nAmended)
{
    if (msc_debug_dex) PrintToLog("%s(%s, %d)\n", __func__, addressSeller, propertyId);

    if (!DEx_offerExists(addressSeller, propertyId)) {
        return (DEX_ERROR_SELLOFFER -12); // offer does not exist
    }

    int rc = DEx_offerDestroy(addressSeller, propertyId);

    if (rc == 0) {
        // if the old offer was destroyed successfully, try to create a new one
        rc = DEx_offerCreate(addressSeller, propertyId, amountOffered, block, amountDesired, minAcceptFee, paymentWindow, txid, nAmended);
    }

    return rc;
}

/**
 * Creates a new accept order.
 *
 * @return 0 if everything is OK
 */
int DEx_acceptCreate(const std::string& addressTaker, const std::string& addressMaker, uint32_t propertyId, int64_t amountAccepted, int block, int64_t feePaid, uint64_t* nAmended)
{
    int rc = DEX_ERROR_ACCEPT -10;
    const std::string keySellOffer = STR_SELLOFFER_ADDR_PROP_COMBO(addressMaker, propertyId);
    const std::string keyAcceptOrder = STR_ACCEPT_ADDR_PROP_ADDR_COMBO(addressMaker, addressTaker, propertyId);

    OfferMap::const_iterator my_it = my_offers.find(keySellOffer);

    if (my_it == my_offers.end()) {
        PrintToLog("%s(): rejected: no matching sell offer for accept order found\n", __func__);
        return (DEX_ERROR_ACCEPT -15);
    }

    const CMPOffer& offer = my_it->second;

    if (msc_debug_dex) PrintToLog("%s(): found a matching sell offer [seller: %s, buyer: %s, property: %d)\n", __func__,
                    addressMaker, addressTaker, propertyId);

    // the older accept is the valid one: do not accept any new ones!
    if (DEx_acceptExists(addressMaker, propertyId, addressTaker)) {
        PrintToLog("%s(): rejected: an accept order from this same maker for this same offer already exists\n", __func__);
        return DEX_ERROR_ACCEPT -205;
    }

    // ensure the correct LTC fee was paid in this acceptance message
    if (msc_debug_dex) PrintToLog("%s() Checking: feePaid: %d, offer.getMinFee(): %d\n",__func__, feePaid, offer.getMinFee());

    if (feePaid < offer.getMinFee()) {
        PrintToLog("%s(): rejected: transaction fee too small [%d < %d]\n", __func__, feePaid, offer.getMinFee());
        return DEX_ERROR_ACCEPT -105;
    }

    if (offer.getOption() == 1)
    {   // if market maker is buying tokens

        if (msc_debug_dex)
        {
            PrintToLog("getProperty: %d\n",offer.getProperty());
            PrintToLog("getOfferAmountOriginal: %d\n",offer.getOfferAmountOriginal());
            PrintToLog("getLTCDesiredOriginal: %d\n",offer.getLTCDesiredOriginal());
        }

        if (amountAccepted > offer.getOfferAmountOriginal()) {
            amountAccepted = offer.getOfferAmountOriginal();
        }

        int64_t amountInBalance = getMPbalance(addressTaker, propertyId, BALANCE);

        if (msc_debug_dex) PrintToLog("%s(): amountInBalance: %d, amountAccepted: %d\n",__func__, amountInBalance, amountAccepted);

        if (amountInBalance == 0){
            PrintToLog("%s(): rejected: amount of token in seller  is zero \n",__func__);
            return rc;
        }

        if (amountInBalance >= amountAccepted) {
            assert(update_tally_map(addressTaker, propertyId, -amountAccepted, BALANCE));
            assert(update_tally_map(addressTaker, propertyId, amountAccepted, ACCEPT_RESERVE));
        } else {
            if (msc_debug_dex) PrintToLog("amountInBalance < amountAccepted ???\n");
        }

        CMPAccept acceptOffer(amountAccepted, block, offer.getBlockTimeLimit(), offer.getProperty(), offer.getOfferAmountOriginal(), offer.getLTCDesiredOriginal(), offer.getHash());
        my_accepts.insert(std::make_pair(keyAcceptOrder, acceptOffer));

        return 0;
    }

    int64_t amountReserved = 0;
    int64_t amountRemainingForSale = getMPbalance(addressMaker, propertyId, SELLOFFER_RESERVE);

    // ensure the buyer only can reserve the amount that is still available
    if (amountRemainingForSale >= amountAccepted) {
        amountReserved = amountAccepted;
    } else {
        amountReserved = amountRemainingForSale;
        if (msc_debug_dex) PrintToLog("%s(): buyer wants to reserve %d tokens, but only %d tokens are available\n", __func__, amountAccepted, amountRemainingForSale);
    }

    if (amountReserved > 0) {
        assert(update_tally_map(addressMaker, propertyId, -amountReserved, SELLOFFER_RESERVE));
        assert(update_tally_map(addressMaker, propertyId, amountReserved, ACCEPT_RESERVE));

        CMPAccept acceptOffer(amountReserved, block, offer.getBlockTimeLimit(), offer.getProperty(), offer.getOfferAmountOriginal(), offer.getLTCDesiredOriginal(), offer.getHash());
        my_accepts.insert(std::make_pair(keyAcceptOrder, acceptOffer));

        rc = 0;
    }

    if (nAmended) *nAmended = amountReserved;

    return rc;
}

/**
 * Finalizes an accepted offer.
 *
 * This function is called by handler_block() for each accepted offer that has
 * expired. This function is also called when the purchase has been completed,
 * and the buyer bought everything that was reserved.
 *
 * @return 0 if everything is OK
 */
int DEx_acceptDestroy(const std::string& addressBuyer, const std::string& addressSeller, uint32_t propertyid, bool fForceErase)
{
    int rc = DEX_ERROR_ACCEPT -20;
    CMPOffer* p_offer = DEx_getOffer(addressSeller, propertyid);
    CMPAccept* p_accept = DEx_getAccept(addressSeller, propertyid, addressBuyer);
    bool fReturnToMoney;

    if (!p_accept) return rc; // sanity check

    // if the offer is gone, ACCEPT_RESERVE should go back to seller's BALANCE
    // otherwise move the previously accepted amount back to SELLOFFER_RESERVE
    if (!p_offer) fReturnToMoney = true;

    PrintToLog("%s(): finalize trade [offer=%s, accept=%s]\n", __func__, p_offer->getHash().GetHex(), p_accept->getHash().GetHex());

    // offer exists, determine whether it's the original offer or some random new one
    fReturnToMoney = (p_offer->getHash() == p_accept->getHash()) ? false : true;

    const int64_t amountRemaining = p_accept->getAcceptAmountRemaining();

    if (amountRemaining > 0) {
        TallyType typ = (fReturnToMoney) ? BALANCE : SELLOFFER_RESERVE;
        assert(update_tally_map(addressSeller, propertyid, -amountRemaining, ACCEPT_RESERVE));
        assert(update_tally_map(addressSeller, propertyid, amountRemaining, typ));

    }

    // can only erase when is NOT called from an iterator loop
    if (fForceErase) {
        std::string key = STR_ACCEPT_ADDR_PROP_ADDR_COMBO(addressSeller, addressBuyer, propertyid);
        AcceptMap::iterator it = my_accepts.find(key);

        if (my_accepts.end() != it) {
            my_accepts.erase(it);
        }
    }

    return 0;
}

/**
 * Determines the purchased amount of tokens.
 *
 * The amount is rounded up, which may be in favor of the buyer, to avoid small
 * leftovers of 1 willet. This is not exploitable due to transaction fees.
 *
 * The desired amount must not be zero, and the purchased amount should be checked
 * against the actual amount that is still left for sale.
 *
 * @return The amount of tokens purchased
 */
int64_t calculateDExPurchase(const int64_t amountOffered, const int64_t amountDesired, const int64_t amountPaid)
{
    // conversion
    arith_uint256 amountOffered256 = ConvertTo256(amountOffered);
    arith_uint256 amountDesired256 = ConvertTo256(amountDesired);
    arith_uint256 amountPaid256 = ConvertTo256(amountPaid);

    // actual calculation; round up
    arith_uint256 amountPurchased256 = DivideAndRoundUp((amountPaid256 * amountOffered256), amountDesired256);

    // convert back to int64_t
    return ConvertTo64(amountPurchased256);
}

/**
 * Handles incoming LTC payment for the offer in tradelayer.cpp
 */
int DEx_payment(const uint256& txid, unsigned int vout, const std::string& addressSeller, const std::string& addressBuyer, int64_t amountPaid, int block, uint64_t* nAmended)
{
    if (msc_debug_dex) PrintToLog("%s(%s, %s)\n", __func__, addressSeller, addressBuyer);
    int rc = DEX_ERROR_PAYMENT;
    uint32_t propertyId;

    CMPAccept* p_accept = nullptr;

    // logic here: we look only into main properties if there's some match
    for (propertyId = 1; propertyId < _my_sps->peekNextSPID(); propertyId++)
    {
        CMPSPInfo::Entry sp;
        if (msc_debug_dex) PrintToLog("propertyId: %d\n",propertyId);
        if (!_my_sps->getSP(propertyId, sp)) continue;

        // seller market maker?
        p_accept = DEx_getAccept(addressSeller, propertyId, addressBuyer);

        if (p_accept)
        {
            if (msc_debug_dex) PrintToLog("Found seller market maker!\n");
            break;
        }

        // buyer market maker?
        if (IsFeatureActivated(FEATURE_DEX_BUY, block))
        {
            p_accept = DEx_getAccept(addressBuyer, propertyId, addressSeller);

            if (p_accept)
            {
                if (msc_debug_dex) PrintToLog("Found buyer market maker!\n");
                break;
            }

        }
    }

    if (!p_accept && msc_debug_dex)
    {
       PrintToLog("%s(): ERROR: there must be an active accept order for this payment, seller: %s, buyer: %s\n",__func__, addressSeller, addressBuyer);
       return (DEX_ERROR_PAYMENT -1);
    }

    // -------------------------------------------------------------------------
    const int64_t amountDesired = p_accept->getLTCDesiredOriginal();
    const int64_t amountOffered = p_accept->getOfferAmountOriginal();

    if (msc_debug_dex) PrintToLog("%s(): amountDesired : %d, amountOffered : %d\n",__func__, amountDesired, amountOffered);

    // divide by 0 protection
    if (0 == amountDesired && msc_debug_dex)
    {
        PrintToLog("%s(): ERROR: desired amount of accept order is zero", __func__);
        return (DEX_ERROR_PAYMENT -2);
    }

   /**
    * Plain integer math is used to determine
    * the purchased amount. The purchased amount is rounded up, which may be
    * in favor of the buyer, to avoid small leftovers of 1 willet.
    *
    * This is not exploitable due to transaction fees.
    */
     int64_t amountPurchased = mastercore::calculateDExPurchase(amountOffered, amountDesired, amountPaid);

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

    // adding LTC volume added by this property
    PrintToLog("%s(): block: %d, propertyId: %d. amountPaid (LTC): %d\n",__func__, block, propertyId, amountPaid);
    MapLTCVolume[block][propertyId] += amountPaid;

    const arith_uint256 amountDesired256  = ConvertTo256(amountDesired);
    const arith_uint256 amountOffered256 = ConvertTo256(amountOffered);
    const arith_uint256 unitPrice256 = (ConvertTo256(COIN) * amountDesired256) / amountOffered256;

    const int64_t unitPrice = (isPropertyDivisible(propertyId)) ? ConvertTo64(unitPrice256) : ConvertTo64(unitPrice256) / COIN;

    // adding last price
    lastPrice[propertyId] = unitPrice;

    // adding numerator of vwap
    tokenvwap[propertyId][block].push_back(std::make_pair(unitPrice, amountPurchased));

    // saving DEx token volume
    MapTokenVolume[block][propertyId] += amountPurchased;

    // adding Last token/ ltc price
    rational_t market_pricetokens_LTC(amountPurchased, amountPaid);
    int64_t market_p_tokens_LTC = mastercore::RationalToInt64(market_pricetokens_LTC);
    market_priceMap[LTC][propertyId] = market_p_tokens_LTC;

    if(msc_debug_dex) PrintToLog("%s(): amountPaid for propertyId : %d,  inside MapLTCVolume: %d, market_p_tokens_LTC : %d\n", __func__, propertyId, amountPaid, market_p_tokens_LTC);

    // -------------------------------------------------------------------------
    if (msc_debug_dex) PrintToLog("amountPurchased: %d\n",amountPurchased);
    const int64_t amountRemaining = p_accept->getAcceptAmountRemaining(); // actual amount desired, in the Accept

    if (msc_debug_dex) PrintToLog(
    "%s(): LTC desired: %s, offered amount: %s, amount to purchase: %s, amount remaining: %s\n", __func__,
    FormatDivisibleMP(amountDesired), FormatDivisibleMP(amountOffered),
    FormatDivisibleMP(amountPurchased), FormatDivisibleMP(amountRemaining));

    // if units_purchased is greater than what's in the Accept, the buyer gets only what's in the Accept
    if (amountRemaining < amountPurchased)
    {
        amountPurchased = amountRemaining;
        if (nAmended) *nAmended = amountPurchased;
    }

    if (msc_debug_dex) PrintToLog("amountPurchased: %d",amountPurchased);

    if (amountPurchased > 0)
    {
        if(msc_debug_dex) PrintToLog("%s(): seller %s offered %s %s for %s LTC\n", __func__,
	      addressSeller, FormatDivisibleMP(amountOffered), strMPProperty(propertyId), FormatDivisibleMP(amountDesired));

        if(msc_debug_dex) PrintToLog("%s: buyer %s pays %s LTC to purchase %s %s\n", __func__,
	      addressBuyer, FormatDivisibleMP(amountPaid), FormatDivisibleMP(amountPurchased), strMPProperty(propertyId));

        assert(update_tally_map(addressSeller, propertyId, -amountPurchased, ACCEPT_RESERVE));
        assert(update_tally_map(addressBuyer, propertyId, amountPurchased, BALANCE));

        if(msc_debug_dex) PrintToLog("AmountPurchased : %d\n",amountPurchased);

        bool valid = true;
        p_txlistdb->recordPaymentTX(txid, valid, block, vout, propertyId, amountPurchased, amountPaid, addressBuyer, addressSeller);

        rc = 0;
        if(msc_debug_dex) PrintToLog("#######################################################\n");
    }

    // reduce the amount of units still desired by the buyer and if 0 destroy the Accept order
    if (p_accept->reduceAcceptAmountRemaining_andIsZero(amountPurchased))
    {
        if(msc_debug_dex) PrintToLog("p_accept->reduceAcceptAmountRemaining_andIsZero true\n");

        const int64_t reserveSell = getMPbalance(addressSeller, propertyId, SELLOFFER_RESERVE);
        const int64_t reserveAccept = getMPbalance(addressSeller, propertyId, ACCEPT_RESERVE);

        if(msc_debug_dex) PrintToLog("reserveSell: %d, reserveAccept: %d\n",reserveSell, reserveAccept);

        DEx_acceptDestroy(addressBuyer, addressSeller, propertyId, true);

        // delete the Offer object if there is nothing in its Reserves -- everything got puchased and paid for
        if (0 == reserveSell && 0 == reserveAccept)
        {
            if(msc_debug_dex) PrintToLog("0 == reserveSell && 0 == reserveAccept true\n");
            DEx_offerDestroy(addressSeller, propertyId);
        }

        rc = 0;
    }

    return rc;
}

unsigned int eraseExpiredAccepts(int blockNow)
{
    unsigned int how_many_erased = 0;
    AcceptMap::iterator it = my_accepts.begin();

    while (my_accepts.end() != it) {
        const CMPAccept& acceptOrder = it->second;

        int blocksSinceAccept = blockNow - acceptOrder.getAcceptBlock();
        int blocksPaymentWindow = static_cast<int>(acceptOrder.getBlockTimeLimit());

        if (blocksSinceAccept >= blocksPaymentWindow) {
            PrintToLog("%s(): erasing at block: %d, order confirmed at block: %d, payment window: %d\n",
                    __func__, blockNow, acceptOrder.getAcceptBlock(), acceptOrder.getBlockTimeLimit());

            // extract the seller, buyer and property from the key
            std::vector<std::string> vstr(3);
            boost::split(vstr, it->first, boost::is_any_of("-+"), boost::token_compress_on);
            const std::string& addressSeller = vstr[0];
            uint32_t propertyId = atoi(vstr[1]);
            const std::string& addressBuyer = vstr[2];

            DEx_acceptDestroy(addressBuyer, addressSeller, propertyId);

            my_accepts.erase(it++);

            ++how_many_erased;

        } else it++;
    }

    return how_many_erased;
}

} // namespace mastercore

max_stars_repo_name: ogreckoner/BlockPo-to-Tradelayer

max_issues_repo_name: ogreckoner/BlockPo-to-Tradelayer

max_forks_repo_name: TradeLayerDesk/BlockPo-to-Tradelayer


text:
/*
 * Copyright (C) 2012-2014 Open Source Robotics Foundation
 *
 * 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 _SENSORTYPES_HH_
#define _SENSORTYPES_HH_

#include <vector>
#include <boost/shared_ptr.hpp>
#include "gazebo/util/system.hh"

/// \file
/// \ingroup gazebo_sensors
/// \brief Forward declarations and typedefs for sensors
namespace gazebo
{
  /// \ingroup gazebo_sensors
  /// \brief Sensors namespace
  namespace sensors
  {
    class Sensor;
    class RaySensor;
    class CameraSensor;
    class MultiCameraSensor;
    class DepthCameraSensor;
    class ContactSensor;
    class ImuSensor;
    class GpuRaySensor;
    class RFIDSensor;
    class RFIDTag;
    class SonarSensor;
    class ForceTorqueSensor;
    class GpsSensor;
    class Noise;
    class GaussianNoiseModel;
    class ImageGaussianNoiseModel;
    class WirelessTransceiver;
    class WirelessTransmitter;
    class WirelessReceiver;

    /// \def SensorPtr
    /// \brief Shared pointer to Sensor
    typedef boost::shared_ptr<Sensor> SensorPtr;

    /// \def RaySensorPtr
    /// \brief Shared pointer to RaySensor
    typedef boost::shared_ptr<RaySensor> RaySensorPtr;

    /// \def CameraSensorPtr
    /// \brief Shared pointer to CameraSensor
    typedef boost::shared_ptr<CameraSensor> CameraSensorPtr;

    /// \def MultiCameraSensorPtr
    /// \brief Shared pointer to MultiCameraSensor
    typedef boost::shared_ptr<MultiCameraSensor> MultiCameraSensorPtr;

    /// \def DepthCameraSensorPtr
    /// \brief Shared pointer to DepthCameraSensor
    typedef boost::shared_ptr<DepthCameraSensor> DepthCameraSensorPtr;

    /// \def ContactSensorPtr
    /// \brief Shared pointer to ContactSensor
    typedef boost::shared_ptr<ContactSensor> ContactSensorPtr;

    /// \def ImuSensorPtr
    /// \brief Shared pointer to ImuSensor
    typedef boost::shared_ptr<ImuSensor> ImuSensorPtr;

    /// \def GpuRaySensorPtr
    /// \brief Shared pointer to GpuRaySensor
    typedef boost::shared_ptr<GpuRaySensor> GpuRaySensorPtr;

    /// \def RFIDSensorPtr
    /// \brief Shared pointer to RFIDSensor
    typedef boost::shared_ptr<RFIDSensor> RFIDSensorPtr;

    /// \def RFIDTagPtr
    /// \brief Shared pointer to RFIDTag
    typedef boost::shared_ptr<RFIDTag> RFIDTagPtr;

    /// \def SonarSensorPtr
    /// \brief Shared pointer to SonarSensor
    typedef boost::shared_ptr<SonarSensor> SonarSensorPtr;

    /// \def ForceTorqueSensorPtr
    /// \brief Shared pointer to ForceTorqueSensor
    typedef boost::shared_ptr<ForceTorqueSensor> ForceTorqueSensorPtr;

    /// \def GpsSensorPtr
    /// \brief Shared pointer to GpsSensor
    typedef boost::shared_ptr<GpsSensor> GpsSensorPtr;

    /// \def NoisePtr
    /// \brief Shared pointer to Noise
    typedef boost::shared_ptr<Noise> NoisePtr;

    /// \def GaussianNoisePtr
    /// \brief Shared pointer to Noise
    typedef boost::shared_ptr<GaussianNoiseModel> GaussianNoiseModelPtr;

    /// \brief Shared pointer to Noise
    typedef boost::shared_ptr<ImageGaussianNoiseModel>
        ImageGaussianNoiseModelPtr;

    /// \def WirelessTransceiverPtr
    /// \brief Shared pointer to WirelessTransceiver
    typedef boost::shared_ptr<WirelessTransceiver> WirelessTransceiverPtr;

    /// \def WirelessTransmitterPtr
    /// \brief Shared pointer to WirelessTransmitter
    typedef boost::shared_ptr<WirelessTransmitter> WirelessTransmitterPtr;

    /// \def WirelessReceiverPtr
    /// \brief Shared pointer to WirelessReceiver
    typedef boost::shared_ptr<WirelessReceiver> WirelessReceiverPtr;

    /// \def Sensor_V
    /// \brief Vector of Sensor shared pointers
    typedef std::vector<SensorPtr> Sensor_V;

    /// \def RaySensor_V
    /// \brief Vector of RaySensor shared pointers
    typedef std::vector<RaySensorPtr> RaySensor_V;

    /// \def CameraSensor_V
    /// \brief Vector of CameraSensor shared pointers
    typedef std::vector<CameraSensorPtr> CameraSensor_V;

    /// \def MultiCameraSensor_V
    /// \brief Vector of MultiCameraSensor shared pointers
    typedef std::vector<MultiCameraSensorPtr> MultiCameraSensor_V;

    /// \def DepthCameraSensor_V
    /// \brief Vector of DepthCameraSensor shared pointers
    typedef std::vector<DepthCameraSensorPtr> DepthCameraSensor_V;

    /// \def ContactSensor_V
    /// \brief Vector of ContactSensor shared pointers
    typedef std::vector<ContactSensorPtr> ContactSensor_V;

    /// \def ImuSensor_V
    /// \brief Vector of ImuSensor shared pointers
    typedef std::vector<ImuSensorPtr> ImuSensor_V;

    /// \def GpuRaySensor_V
    /// \brief Vector of GpuRaySensor shared pointers
    typedef std::vector<GpuRaySensorPtr> GpuRaySensor_V;

    /// \def RFIDSensor_V
    /// \brief Vector of RFIDSensors
    typedef std::vector<RFIDSensor> RFIDSensor_V;

    /// \def RFIDTag_V
    /// \brief Vector of RFIDTags
    typedef std::vector<RFIDTag> RFIDTag_V;

    /// \def WirelessTransceiver_V
    /// \brief Vector of WirelessTransceiver
    typedef std::vector<WirelessTransceiver> WirelessTransceiver_V;

    /// \def WirelessTransmitter_V
    /// \brief Vector of WirelessTransmitter
    typedef std::vector<WirelessTransmitter> WirelessTransmitter_V;

    /// \def WirelessReceiver_V
    /// \brief Vector of WirelessReceiver
    typedef std::vector<WirelessReceiver> WirelessReceiver_V;

    /// \}
  }
}
#endif

ext: hh

max_stars_repo_name: hyunoklee/Gazebo

max_issues_repo_name: hyunoklee/Gazebo

max_forks_repo_name: hyunoklee/Gazebo


text:
// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#ifndef VSOMEIP_TC_TRACE_HEADER_HPP
#define VSOMEIP_TC_TRACE_HEADER_HPP

#include <memory>

#include <vsomeip/primitive_types.hpp>

#include <boost/asio/ip/address_v4.hpp>

#define VSOMEIP_TRACE_HEADER_SIZE 10

namespace vsomeip {

class endpoint;

namespace tc {

enum class protocol_e : uint8_t {
    local = 0x0,
    udp = 0x1,
    tcp = 0x2,
    unknown = 0xFF
};

struct trace_header {
    bool prepare(const std::shared_ptr<endpoint> &_endpoint, bool _is_sending,
            instance_t _instance);
    bool prepare(const endpoint* _endpoint, bool _is_sending,
            instance_t _instance);
    void prepare(const boost::asio::ip::address_v4 &_address,
                 std::uint16_t _port, protocol_e _protocol, bool _is_sending,
                 instance_t _instance);

    byte_t data_[VSOMEIP_TRACE_HEADER_SIZE];
};

} // namespace tc
} // namespace vsomeip

#endif // VSOMEIP_TC_TRACE_HEADER_HPP

max_stars_repo_name: MicrochipTech/some-ip

max_issues_repo_name: MicrochipTech/some-ip

max_forks_repo_name: MicrochipTech/some-ip


text:
//  (C) Copyright Gennadiy Rozental 2001.
//  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)

//  See http://www.boost.org/libs/test for the library home page.
//
//  File        : $RCSfile$
//
//  Version     : $Revision: 74640 $
//
//  Description : defines auto_test_unit_registrar
// ***************************************************************************

#ifndef BOOST_TEST_TREE_AUTO_REGISTRATION_HPP_100211GER
#define BOOST_TEST_TREE_AUTO_REGISTRATION_HPP_100211GER

// Boost.Test
#include <boost/test/detail/config.hpp>
#include <boost/test/tree/decorator.hpp>
#include <boost/test/tree/test_unit.hpp>

// STL
#include <boost/test/detail/suppress_warnings.hpp>
#include <list>

//____________________________________________________________________________//

namespace boost
{
namespace unit_test
{
namespace ut_detail
{

// ************************************************************************** //
// **************           auto_test_unit_registrar           ************** //
// ************************************************************************** //

struct BOOST_TEST_DECL auto_test_unit_registrar
{
    // Constructors
    auto_test_unit_registrar(test_case* tc, decorator::collector_t& decorators,
                             counter_t exp_fail = 0);
    explicit auto_test_unit_registrar(const_string ts_name,
                                      const_string ts_file, std::size_t ts_line,
                                      decorator::collector_t& decorators);
    explicit auto_test_unit_registrar(test_unit_generator const& tc_gen,
                                      decorator::collector_t& decorators);
    explicit auto_test_unit_registrar(
        boost::shared_ptr<test_unit_generator> tc_gen,
        decorator::collector_t& decorators);
    explicit auto_test_unit_registrar(int);
};

} // namespace ut_detail
} // namespace unit_test
} // namespace boost

#include <boost/test/detail/enable_warnings.hpp>

#endif // BOOST_TEST_TREE_AUTO_REGISTRATION_HPP_100211GER

max_stars_repo_name: sotaoverride/backup

max_issues_repo_name: sotaoverride/backup

max_forks_repo_name: sotaoverride/backup


text:
/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2019 Sylko Olzscher
 *
 */

#include "test-crypto-005.h"
#include <iostream>
#include <boost/test/unit_test.hpp>
#include <crypto/print.h>
#include <openssl/err.h>

namespace cyng
{
	bool test_crypto_005()
	{

		//auto dec = crypto::hash_string("hello, world", "sha256");

		////
		////	result is: 09ca7e4eaa6e8ae9c7d261167129184883644d07dfba7cbfbc4c8a2e08360d5b
		////
		//BOOST_CHECK_EQUAL(dec.size(), 32);

		//BOOST_CHECK_EQUAL(dec.at(0), 0x09);
		//BOOST_CHECK_EQUAL(dec.at(1), 0xca);
		//BOOST_CHECK_EQUAL(dec.at(31), 0x5b);

		OpenSSL_add_all_algorithms();
		ERR_load_crypto_strings();
		ERR_load_BIO_strings();
		SSL_load_error_strings();
		//OPENSSL_no_config();

		//crypto::dump_evp("private.pem");
		//crypto::dump_evp("cakey.pem");
		crypto::dump_x509("mySignedCert.pem");

		return true;
	}

}

max_stars_repo_name: BitStumbler/crypto

max_issues_repo_name: BitStumbler/crypto

max_forks_repo_name: BitStumbler/crypto


text:
/*=============================================================================
    Copyright (c) 2002-2003 Hartmut Kaiser
    http://spirit.sourceforge.net/

    Use, modification and distribution is subject to the Boost Software
    License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
    http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
///////////////////////////////////////////////////////////////////////////////
//  This example shows the usage of the refactoring parser family parsers
//  See the "Refactoring Parsers" chapter in the User's Guide.

#include <iostream>
#include <string>

#include <boost/spirit/include/classic_core.hpp>
#include <boost/spirit/include/classic_refactoring.hpp>

///////////////////////////////////////////////////////////////////////////////
// used namespaces
using namespace std;
using namespace BOOST_SPIRIT_CLASSIC_NS;

///////////////////////////////////////////////////////////////////////////////
// actor, used by the refactor_action_p test
struct refactor_action_actor
{
    refactor_action_actor (std::string &str_) : str(str_) {}

    template <typename IteratorT>
    void operator() (IteratorT const &first, IteratorT const &last) const
    {
        str = std::string(first, last-first);
    }

    std::string &str;
};

///////////////////////////////////////////////////////////////////////////////
// main entry point
int main()
{
    parse_info<> result;
    char const *test_string = "Some string followed by a newline\n";

///////////////////////////////////////////////////////////////////////////////
//
//  1. Testing the refactor_unary_d parser
//
//  The following test should successfully parse the test string, because the
//
//      refactor_unary_d[
//          *anychar_p - '\n'
//      ]
//
//  is refactored into
//
//      *(anychar_p - '\n').
//
///////////////////////////////////////////////////////////////////////////////

    result = parse(test_string, refactor_unary_d[*anychar_p - '\n'] >> '\n');

    if (result.full)
    {
        cout << "Successfully refactored an unary!" << endl;
    }
    else
    {
        cout << "Failed to refactor an unary!" << endl;
    }

//  Parsing the same test string without refactoring fails, because the
//  *anychar_p eats up all the input up to the end of the input string.

    result = parse(test_string, (*anychar_p - '\n') >> '\n');

    if (result.full)
    {
        cout
            << "Successfully parsed test string (should not happen)!"
            << endl;
    }
    else
    {
        cout
            << "Correctly failed parsing the test string (without refactoring)!"
            << endl;
    }
    cout << endl;

///////////////////////////////////////////////////////////////////////////////
//
//  2. Testing the refactor_action_d parser
//
//  The following test should successfully parse the test string, because the
//
//      refactor_action_d[
//          (*(anychar_p - '$'))[refactor_action_actor(str)] >> '$'
//      ]
//
//  is refactored into
//
//      (*(anychar_p - '$') >> '$')[refactor_action_actor(str)].
//
///////////////////////////////////////////////////////////////////////////////

    std::string str;
    char const *test_string2 = "Some test string ending with a $";

    result =
        parse(test_string2,
            refactor_action_d[
                (*(anychar_p - '$'))[refactor_action_actor(str)] >> '$'
            ]
        );

    if (result.full && str == std::string(test_string2))
    {
        cout << "Successfully refactored an action!" << endl;
        cout << "Parsed: \"" << str << "\"" << endl;
    }
    else
    {
        cout << "Failed to refactor an action!" << endl;
    }

//  Parsing the same test string without refactoring fails, because the
//  the attached actor gets called only for the first part of the string
//  (without the '$')

    result =
        parse(test_string2,
            (*(anychar_p - '$'))[refactor_action_actor(str)] >> '$'
        );

    if (result.full && str == std::string(test_string2))
    {
        cout << "Successfully parsed test string!" << endl;
        cout << "Parsed: \"" << str << "\"" << endl;
    }
    else
    {
        cout
            << "Correctly failed parsing the test string (without refactoring)!"
            << endl;
        cout << "Parsed instead: \"" << str << "\"" << endl;
    }
    cout << endl;

///////////////////////////////////////////////////////////////////////////////
//
//  3. Testing the refactor_action_d parser with an embedded (nested)
//  refactor_unary_p parser
//
//  The following test should successfully parse the test string, because the
//
//      refactor_action_unary_d[
//          ((*anychar_p)[refactor_action_actor(str)] - '$')
//      ] >> '$'
//
//  is refactored into
//
//      (*(anychar_p - '$'))[refactor_action_actor(str)] >> '$'.
//
///////////////////////////////////////////////////////////////////////////////

    const refactor_action_gen<refactor_unary_gen<> > refactor_action_unary_d =
        refactor_action_gen<refactor_unary_gen<> >(refactor_unary_d);

    result =
        parse(test_string2,
            refactor_action_unary_d[
                ((*anychar_p)[refactor_action_actor(str)] - '$')
            ] >> '$'
        );

    if (result.full)
    {
        cout
            << "Successfully refactored an action attached to an unary!"
            << endl;
        cout << "Parsed: \"" << str << "\"" << endl;
    }
    else
    {
        cout << "Failed to refactor an action!" << endl;
    }

//  Parsing the same test string without refactoring fails, because the
//  anychar_p eats up all the input up to the end of the string

    result =
        parse(test_string2,
            ((*anychar_p)[refactor_action_actor(str)] - '$') >> '$'
        );

    if (result.full)
    {
        cout << "Successfully parsed test string!" << endl;
        cout << "Parsed: \"" << str << "\"" << endl;
    }
    else
    {
        cout
            << "Correctly failed parsing the test string (without refactoring)!"
            << endl;
        cout << "Parsed instead: \"" << str << "\"" << endl;
    }
    cout << endl;

    return 0;
}


text:
/**
 * Copyright (c) 2011, 2012
 * Claudio Kopper <claudio.kopper@icecube.wisc.edu>
 * and the IceCube Collaboration <http://www.icecube.wisc.edu>
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 *
 * $Id: I3TauSanitizer.cxx 148769 2016-07-26 16:54:57Z olivas $
 *
 * @file I3TauSanitizer.cxx
 * @version $Revision: 148769 $
 * @date $Date: 2016-07-26 10:54:57 -0600 (Tue, 26 Jul 2016) $
 * @author Claudio Kopper
 */

#ifndef __STDC_FORMAT_MACROS
#define __STDC_FORMAT_MACROS
#endif
#include <inttypes.h>

#include "icetray/I3Module.h"
#include "icetray/I3ConditionalModule.h"

#include <string>
#include <cmath>

#include <boost/foreach.hpp>

#include "dataclasses/physics/I3Particle.h"
#include "dataclasses/physics/I3MCTree.h"
#include "dataclasses/physics/I3MCTreeUtils.h"
#include "dataclasses/I3Constants.h"

#include "simclasses/I3MMCTrack.h"

/**
 * Sets taus with length==0 or NaN to shape "Dark".
 */
class I3TauSanitizer : public I3ConditionalModule
{
public:
    /**
     * Builds an instance of this class
     */
    I3TauSanitizer(const I3Context& ctx);

    /**
     * Destroys an instance of this class
     */
    virtual ~I3TauSanitizer();

    /**
     * This module takes a configuration parameter and so it must be configured.
     */
    virtual void Configure();

    /**
     * The module needs to process Physics frames
     */
    virtual void DAQ(I3FramePtr frame);

private:
    // parameters

    /// Parameter: Name of the I3MCTree frame object.
    std::string inputMCTreeName_;

    // /// Parameter: Name of the I3MMCTrackList frame object.
    // std::string MMCTrackListName_;

    /// Parameter: Name of the output I3MCTree frame object. If identical to the
    /// input or empty, the input object will be replaced.
    std::string outputMCTreeName_;

private:
    // default, assignment, and copy constructor declared private
    I3TauSanitizer();
    I3TauSanitizer(const I3TauSanitizer&);
    I3TauSanitizer& operator=(const I3TauSanitizer&);

    SET_LOGGER("I3TauSanitizer");
};

// The module
I3_MODULE(I3TauSanitizer);

I3TauSanitizer::I3TauSanitizer(const I3Context& context)
: I3ConditionalModule(context)
{

    inputMCTreeName_="I3MCTree";
    AddParameter("InputMCTreeName",
                 "Name of the I3MCTree frame object.",
                 inputMCTreeName_);

    // inputMCTreeName_="MMCTrackList";
    // AddParameter("MMCTrackListName",
    //              "Name of the I3MMCTrackList frame object.",
    //              MMCTrackListName_);

    inputMCTreeName_="I3MCTree_sanitized";
    AddParameter("OutputMCTreeName",
                 "Name of the output I3MCTree frame object. If identical to the\n"
                 "input or empty, the input object will be replaced.",
                 outputMCTreeName_);

    // add an outbox
    AddOutBox("OutBox");

}

I3TauSanitizer::~I3TauSanitizer()
{
    log_trace("%s", __PRETTY_FUNCTION__);
}

void I3TauSanitizer::Configure()
{
    log_trace("%s", __PRETTY_FUNCTION__);

    GetParameter("InputMCTreeName", inputMCTreeName_);
    // GetParameter("MMCTrackListName", MMCTrackListName_);
    GetParameter("OutputMCTreeName", outputMCTreeName_);

    if (inputMCTreeName_=="")
        log_fatal("The \"InputMCTreeName\" parameter must not be empty.");
}

void I3TauSanitizer::DAQ(I3FramePtr frame)
{
    log_trace("%s", __PRETTY_FUNCTION__);

    I3MCTreeConstPtr inputMCTree = frame->Get<I3MCTreeConstPtr>(inputMCTreeName_);
    if (!inputMCTree) {
        log_debug("Frame does not contain an I3MCTree named \"%s\".",
                  inputMCTreeName_.c_str());
        PushFrame(frame);
        return;
    }

    // I3MMCTrackListConstPtr MMCTrackList = frame->Get<I3MMCTrackListConstPtr>(MMCTrackListName_);
    // if (!MMCTrackList) log_fatal("Frame does not contain an I3MMCTrackList named \"%s\".",
    //                              MMCTrackListName_.c_str());

    // allocate the output I3MCTree
    I3MCTreePtr outputMCTree(new I3MCTree(*inputMCTree));

    // set all taus without lengths to "Dark"
    for (I3MCTree::iterator it = outputMCTree->begin();
         it != outputMCTree->end();
         ++it)
    {
        if ((it->GetType() != I3Particle::TauPlus) && (it->GetType() != I3Particle::TauMinus))
            continue;

        if (std::isnan(it->GetLength()))
        {
            log_warn("Particle (%" PRIu64 ",%i) has NaN length. setting to shape \"Dark\".",
                it->GetMajorID(),
                it->GetMinorID());
            it->SetShape(I3Particle::Dark);
        }
        else if (it->GetLength() <= 0.)
        {
            log_warn("Particle (%" PRIu64 ",%i) has length %fm. setting to shape \"Dark\".",
                it->GetMajorID(),
                it->GetMinorID(),
                it->GetLength()/I3Units::m);
            it->SetShape(I3Particle::Dark);
        }
    }

    // store the output I3MCTree
    if ((outputMCTreeName_=="") || (outputMCTreeName_==inputMCTreeName_)) {
        frame->Delete(inputMCTreeName_);
        frame->Put(inputMCTreeName_, outputMCTree);
    } else {
        frame->Put(outputMCTreeName_, outputMCTree);
    }

    // that's it!
    PushFrame(frame);
}

ext: cxx


text:
//
// Copyright (c) 2019-2022 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
//
// 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_MYSQL_DETAIL_PROTOCOL_SERIALIZATION_HPP
#define BOOST_MYSQL_DETAIL_PROTOCOL_SERIALIZATION_HPP

#include <boost/endian/conversion.hpp>
#include <type_traits>
#include <algorithm>
#include <boost/mysql/detail/protocol/protocol_types.hpp>
#include <boost/mysql/detail/protocol/serialization_context.hpp>
#include <boost/mysql/detail/protocol/deserialization_context.hpp>
#include <boost/mysql/detail/auxiliar/bytestring.hpp>
#include <boost/mysql/value.hpp>
#include <boost/mysql/error.hpp>

namespace boost {
namespace mysql {
namespace detail {

enum class serialization_tag
{
    none,
    plain_int,
    enumeration,
    struct_with_fields
};

template <class T>
constexpr serialization_tag get_serialization_tag();

template <class T, serialization_tag=get_serialization_tag<T>()>
struct serialization_traits;

template <class... Types>
errc deserialize(deserialization_context& ctx, Types&... output) noexcept;

template <class... Types>
void serialize(serialization_context& ctx, const Types&... input) noexcept;

template <class... Types>
std::size_t get_size(const serialization_context& ctx, const Types&... input) noexcept;

// Plain integers
template <class T>
struct serialization_traits<T, serialization_tag::plain_int>
{
    static errc deserialize_(deserialization_context& ctx, T& output) noexcept;
    static void serialize_(serialization_context& ctx, T input) noexcept;
    static constexpr std::size_t get_size_(const serialization_context&, T) noexcept { return sizeof(T); }
};

// int3
template <>
struct serialization_traits<int3, serialization_tag::none>
{
    static inline errc deserialize_(deserialization_context& ctx, int3& output) noexcept
    {
        if (!ctx.enough_size(3))
            return errc::incomplete_message;
        output.value = boost::endian::load_little_u24(ctx.first());
        ctx.advance(3);
        return errc::ok;
    }
    static inline void serialize_(serialization_context& ctx, int3 input) noexcept
    {
        boost::endian::store_little_u24(ctx.first(), input.value);
        ctx.advance(3);
    }
    static inline std::size_t get_size_(const serialization_context&, int3) noexcept { return 3; }
};

// int_lenenc
template <>
struct serialization_traits<int_lenenc, serialization_tag::none>
{
    static inline errc deserialize_(deserialization_context& ctx, int_lenenc& output) noexcept;
    static inline void serialize_(serialization_context& ctx, int_lenenc input) noexcept;
    static inline std::size_t get_size_(const serialization_context&, int_lenenc input) noexcept;
};

// string_fixed
template <std::size_t N>
struct serialization_traits<string_fixed<N>, serialization_tag::none>
{
    static errc deserialize_(deserialization_context& ctx, string_fixed<N>& output) noexcept
    {
        if (!ctx.enough_size(N))
            return errc::incomplete_message;
        memcpy(output.data(), ctx.first(), N);
        ctx.advance(N);
        return errc::ok;
    }
    static void serialize_(serialization_context& ctx, const string_fixed<N>& input) noexcept
    {
        ctx.write(input.data(), N);
    }
    static constexpr std::size_t get_size_(const serialization_context&, const string_fixed<N>&) noexcept
    {
        return N;
    }
};

// string_null
template <>
struct serialization_traits<string_null, serialization_tag::none>
{
    static inline errc deserialize_(deserialization_context& ctx, string_null& output) noexcept;
    static inline void serialize_(serialization_context& ctx, string_null input) noexcept
    {
        ctx.write(input.value.data(), input.value.size());
        ctx.write(0); // null terminator
    }
    static inline std::size_t get_size_(const serialization_context&, string_null input) noexcept
    {
        return input.value.size() + 1;
    }
};

// string_eof
template <>
struct serialization_traits<string_eof, serialization_tag::none>
{
    static inline errc deserialize_(deserialization_context& ctx, string_eof& output) noexcept;
    static inline void serialize_(serialization_context& ctx, string_eof input) noexcept
    {
        ctx.write(input.value.data(), input.value.size());
    }
    static inline std::size_t get_size_(const serialization_context&, string_eof input) noexcept
    {
        return input.value.size();
    }
};

// string_lenenc
template <>
struct serialization_traits<string_lenenc, serialization_tag::none>
{
    static inline errc deserialize_(deserialization_context& ctx, string_lenenc& output) noexcept;
    static inline void serialize_(serialization_context& ctx, string_lenenc input) noexcept
    {
        serialize(ctx, int_lenenc(input.value.size()));
        ctx.write(input.value.data(), input.value.size());
    }
    static inline std::size_t get_size_(const serialization_context& ctx, string_lenenc input) noexcept
    {
        return get_size(ctx, int_lenenc(input.value.size())) + input.value.size();
    }
};

// Enums
template <class T>
struct serialization_traits<T, serialization_tag::enumeration>
{
    using underlying_type = typename std::underlying_type<T>::type;

    static errc deserialize_(deserialization_context& ctx, T& output) noexcept
    {
        underlying_type value = 0;
        errc err = deserialize(ctx, value);
        output = static_cast<T>(value);
        return err;
    }
    static void serialize_(serialization_context& ctx, T input) noexcept
    {
        serialize(ctx, static_cast<underlying_type>(input));
    }
    static std::size_t get_size_(const serialization_context&, T) noexcept { return sizeof(underlying_type); }
};

// Structs and commands
// To allow a limited way of reflection, structs should
// provide a static member function with signature:
// void apply(Self&, Callable&&), which will invoke Callable
// with each field in the struct as argument (similar to std::apply).
// Making the member function static with a Self template parameter
// allows calling apply with const and non-const objects as self.
// Types fulfilling this requirement will have the below function
// return true
template <class T>
constexpr bool is_struct_with_fields();

template <class T>
struct serialization_traits<T, serialization_tag::struct_with_fields>
{
    static errc deserialize_(deserialization_context& ctx, T& output) noexcept;
    static void serialize_(serialization_context& ctx, const T& input) noexcept;
    static std::size_t get_size_(const serialization_context& ctx, const T& input) noexcept;
};

// Use these to make all messages implement all methods, leaving the not required
// ones with a default implementation. While this is not strictly required,
// it simplifies the testing infrastructure
template <class T>
struct noop_serialize
{
    static inline std::size_t get_size_(const serialization_context&, const T&) noexcept { return 0; }
    static inline void serialize_(serialization_context&, const T&) noexcept {}
};

template <class T>
struct noop_deserialize
{
    static inline errc deserialize_(deserialization_context&, T&) noexcept { return errc::ok; }
};

// Helper to serialize top-level messages
template <class Serializable, class Allocator>
void serialize_message(
    const Serializable& input,
    capabilities caps,
    basic_bytestring<Allocator>& buffer
);

template <class Deserializable>
error_code deserialize_message(
    deserialization_context& ctx,
    Deserializable& output
);

// Helpers for (de) serializing a set of fields
template <class... Types>
void serialize_fields(serialization_context& ctx, const Types&... fields) noexcept;

} // detail
} // mysql
} // boost

#include <boost/mysql/detail/protocol/impl/serialization.hpp>
#include <boost/mysql/detail/protocol/impl/serialization.ipp>

#endif

max_stars_repo_name: anarthal/mysql-asio

max_issues_repo_name: anarthal/mysql-asio

max_forks_repo_name: anarthal/mysql-asio


text:
//
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
//
// 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)
//
// Official repository: https://github.com/cppalliance/json
//

#ifndef BOOST_JSON_KIND_HPP
#define BOOST_JSON_KIND_HPP

#include <boost/json/detail/config.hpp>

BOOST_JSON_NS_BEGIN

/** Constants for identifying the type of a value

    These values are returned from @ref value::kind
*/
enum class kind : unsigned char
{
    /// An @ref array.
    array,

    /// An @ref object.
    object,

    /// A @ref string.
    string,

    /// A `std::int64_t`
    int64,

    /// A `std::uint64_t`
    uint64,

    /// A `double`.
    double_,

    /// A `bool`.
    bool_,

    /// The null value.
    null
};

/** A tag type used to select a @ref value constructor overload.

    The library provides the constant @ref array_kind
    which may be used to select the @ref value constructor
    that creates an empty @ref array.

    @see @ref array_kind
*/
struct array_kind_t
{
};

/** A tag type used to select a @ref value constructor overload.

    The library provides the constant @ref object_kind
    which may be used to select the @ref value constructor
    that creates an empty @ref object.

    @see @ref object_kind
*/
struct object_kind_t
{
};

/** A tag type used to select a @ref value constructor overload.

    The library provides the constant @ref string_kind
    which may be used to select the @ref value constructor
    that creates an empty @ref string.

    @see @ref string_kind
*/
struct string_kind_t
{
};

/** A constant used to select a @ref value constructor overload.

    The library provides this constant to allow efficient
    construction of a @ref value containing an empty @ref array.

    @par Example
    @code
    storage_ptr sp;
    value jv( array_kind, sp ); // sp is an optional parameter
    @endcode

    @see @ref array_kind_t
*/
BOOST_JSON_INLINE_VARIABLE(array_kind, array_kind_t);

/** A constant used to select a @ref value constructor overload.

    The library provides this constant to allow efficient
    construction of a @ref value containing an empty @ref object.

    @par Example
    @code
    storage_ptr sp;
    value jv( object_kind, sp ); // sp is an optional parameter
    @endcode

    @see @ref object_kind_t
*/
BOOST_JSON_INLINE_VARIABLE(object_kind, object_kind_t);

/** A constant used to select a @ref value constructor overload.

    The library provides this constant to allow efficient
    construction of a @ref value containing an empty @ref string.

    @par Example
    @code
    storage_ptr sp;
    value jv( string_kind, sp ); // sp is an optional parameter
    @endcode

    @see @ref string_kind_t
*/
BOOST_JSON_INLINE_VARIABLE(string_kind, string_kind_t);

BOOST_JSON_NS_END

#endif

max_stars_repo_name: Julien-Blanc-tgcm/json

max_issues_repo_name: Julien-Blanc-tgcm/json

max_forks_repo_name: cppalliance-bot/json