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

/**
 * @file
 **/

#include "modules/planning/toolkits/optimizers/road_graph/trajectory_cost.h"

#include <algorithm>
#include <cmath>
#include <limits>
#include <utility>

#include "modules/common/proto/pnc_point.pb.h"

#include "modules/common/configs/vehicle_config_helper.h"
#include "modules/common/math/vec2d.h"
#include "modules/common/util/util.h"
#include "modules/planning/common/planning_gflags.h"

namespace apollo {
namespace planning {

using apollo::common::TrajectoryPoint;
using apollo::common::math::Box2d;
using apollo::common::math::Sigmoid;
using apollo::common::math::Vec2d;

TrajectoryCost::TrajectoryCost(const DpPolyPathConfig &config,
                               const ReferenceLine &reference_line,
                               const bool is_change_lane_path,
                               const std::vector<const Obstacle *> &obstacles,
                               const common::VehicleParam &vehicle_param,
                               const SpeedData &heuristic_speed_data,
                               const common::SLPoint &init_sl_point,
                               const SLBoundary &adc_sl_boundary)
    : config_(config),
      reference_line_(&reference_line),
      is_change_lane_path_(is_change_lane_path),
      vehicle_param_(vehicle_param),
      heuristic_speed_data_(heuristic_speed_data),
      init_sl_point_(init_sl_point),
      adc_sl_boundary_(adc_sl_boundary) {
  const double total_time =
      std::min(heuristic_speed_data_.TotalTime(), FLAGS_prediction_total_time);

  num_of_time_stamps_ = static_cast<uint32_t>(
      std::floor(total_time / config.eval_time_interval()));

  for (const auto *ptr_obstacle : obstacles) {
    if (ptr_obstacle->IsIgnore()) {
      continue;
    } else if (ptr_obstacle->LongitudinalDecision().has_stop()) {
      continue;
    }
    const auto &sl_boundary = ptr_obstacle->PerceptionSLBoundary();

    const double adc_left_l =
        init_sl_point_.l() + vehicle_param_.left_edge_to_center();
    const double adc_right_l =
        init_sl_point_.l() - vehicle_param_.right_edge_to_center();

    if (adc_left_l + FLAGS_lateral_ignore_buffer < sl_boundary.start_l() ||
        adc_right_l - FLAGS_lateral_ignore_buffer > sl_boundary.end_l()) {
      continue;
    }

    bool is_bycycle_or_pedestrian =
        (ptr_obstacle->Perception().type() ==
             perception::PerceptionObstacle::BICYCLE ||
         ptr_obstacle->Perception().type() ==
             perception::PerceptionObstacle::PEDESTRIAN);

    if (ptr_obstacle->IsVirtual()) {
      // Virtual obstacle
      continue;
    } else if (ptr_obstacle->IsStatic() || is_bycycle_or_pedestrian) {
      static_obstacle_sl_boundaries_.push_back(std::move(sl_boundary));
    } else {
      std::vector<Box2d> box_by_time;
      for (uint32_t t = 0; t <= num_of_time_stamps_; ++t) {
        TrajectoryPoint trajectory_point =
            ptr_obstacle->GetPointAtTime(t * config.eval_time_interval());

        Box2d obstacle_box = ptr_obstacle->GetBoundingBox(trajectory_point);
        constexpr double kBuff = 0.5;
        Box2d expanded_obstacle_box =
            Box2d(obstacle_box.center(), obstacle_box.heading(),
                  obstacle_box.length() + kBuff, obstacle_box.width() + kBuff);
        box_by_time.push_back(expanded_obstacle_box);
      }
      dynamic_obstacle_boxes_.push_back(std::move(box_by_time));
    }
  }
}

ComparableCost TrajectoryCost::CalculatePathCost(
    const QuinticPolynomialCurve1d &curve, const double start_s,
    const double end_s, const uint32_t curr_level, const uint32_t total_level) {
  ComparableCost cost;
  double path_cost = 0.0;
  std::function<double(const double)> quasi_softmax = [this](const double x) {
    const double l0 = this->config_.path_l_cost_param_l0();
    const double b = this->config_.path_l_cost_param_b();
    const double k = this->config_.path_l_cost_param_k();
    return (b + std::exp(-k * (x - l0))) / (1.0 + std::exp(-k * (x - l0)));
  };

  for (double curve_s = 0.0; curve_s < (end_s - start_s);
       curve_s += config_.path_resolution()) {
    const double l = curve.Evaluate(0, curve_s);

    path_cost += l * l * config_.path_l_cost() * quasi_softmax(std::fabs(l));

    const double dl = std::fabs(curve.Evaluate(1, curve_s));
    if (IsOffRoad(curve_s + start_s, l, dl, is_change_lane_path_)) {
      cost.cost_items[ComparableCost::OUT_OF_BOUNDARY] = true;
    }

    path_cost += dl * dl * config_.path_dl_cost();

    const double ddl = std::fabs(curve.Evaluate(2, curve_s));
    path_cost += ddl * ddl * config_.path_ddl_cost();
  }
  path_cost *= config_.path_resolution();

  if (curr_level == total_level) {
    const double end_l = curve.Evaluate(0, end_s - start_s);
    path_cost +=
        std::sqrt(end_l - init_sl_point_.l() / 2.0) * config_.path_end_l_cost();
  }
  cost.smoothness_cost = path_cost;
  return cost;
}

bool TrajectoryCost::IsOffRoad(const double ref_s, const double l,
                               const double dl,
                               const bool is_change_lane_path) {
  constexpr double kIgnoreDistance = 5.0;
  if (ref_s - init_sl_point_.s() < kIgnoreDistance) {
    return false;
  }
  Vec2d rear_center(0.0, l);

  const auto &param = common::VehicleConfigHelper::GetConfig().vehicle_param();
  Vec2d vec_to_center(
      (param.front_edge_to_center() - param.back_edge_to_center()) / 2.0,
      (param.left_edge_to_center() - param.right_edge_to_center()) / 2.0);

  Vec2d rear_center_to_center = vec_to_center.rotate(std::atan(dl));
  Vec2d center = rear_center + rear_center_to_center;
  Vec2d front_center = center + rear_center_to_center;

  const double buffer = 0.1;  // in meters
  const double r_w =
      (param.left_edge_to_center() + param.right_edge_to_center()) / 2.0;
  const double r_l = param.back_edge_to_center();
  const double r = std::sqrt(r_w * r_w + r_l * r_l);

  double left_width = 0.0;
  double right_width = 0.0;
  reference_line_->GetLaneWidth(ref_s, &left_width, &right_width);

  double left_bound = std::max(init_sl_point_.l() + r + buffer, left_width);
  double right_bound = std::min(init_sl_point_.l() - r - buffer, -right_width);
  if (rear_center.y() + r + buffer / 2.0 > left_bound ||
      rear_center.y() - r - buffer / 2.0 < right_bound) {
    return true;
  }
  if (front_center.y() + r + buffer / 2.0 > left_bound ||
      front_center.y() - r - buffer / 2.0 < right_bound) {
    return true;
  }

  return false;
}

ComparableCost TrajectoryCost::CalculateStaticObstacleCost(
    const QuinticPolynomialCurve1d &curve, const double start_s,
    const double end_s) {
  ComparableCost obstacle_cost;
  for (double curr_s = start_s; curr_s <= end_s;
       curr_s += config_.path_resolution()) {
    const double curr_l = curve.Evaluate(0, curr_s - start_s);
    for (const auto &obs_sl_boundary : static_obstacle_sl_boundaries_) {
      obstacle_cost += GetCostFromObsSL(curr_s, curr_l, obs_sl_boundary);
    }
  }
  obstacle_cost.safety_cost *= config_.path_resolution();
  return obstacle_cost;
}

ComparableCost TrajectoryCost::CalculateDynamicObstacleCost(
    const QuinticPolynomialCurve1d &curve, const double start_s,
    const double end_s) const {
  ComparableCost obstacle_cost;
  if (dynamic_obstacle_boxes_.empty()) {
    return obstacle_cost;
  }

  double time_stamp = 0.0;
  for (size_t index = 0; index < num_of_time_stamps_;
       ++index, time_stamp += config_.eval_time_interval()) {
    common::SpeedPoint speed_point;
    heuristic_speed_data_.EvaluateByTime(time_stamp, &speed_point);
    double ref_s = speed_point.s() + init_sl_point_.s();
    if (ref_s < start_s) {
      continue;
    }
    if (ref_s > end_s) {
      break;
    }

    const double s = ref_s - start_s;  // s on spline curve
    const double l = curve.Evaluate(0, s);
    const double dl = curve.Evaluate(1, s);

    const common::SLPoint sl = common::util::MakeSLPoint(ref_s, l);
    const Box2d ego_box = GetBoxFromSLPoint(sl, dl);
    for (const auto &obstacle_trajectory : dynamic_obstacle_boxes_) {
      obstacle_cost +=
          GetCostBetweenObsBoxes(ego_box, obstacle_trajectory.at(index));
    }
  }
  constexpr double kDynamicObsWeight = 1e-6;
  obstacle_cost.safety_cost *=
      (config_.eval_time_interval() * kDynamicObsWeight);
  return obstacle_cost;
}

ComparableCost TrajectoryCost::GetCostFromObsSL(
    const double adc_s, const double adc_l, const SLBoundary &obs_sl_boundary) {
  const auto &vehicle_param =
      common::VehicleConfigHelper::Instance()->GetConfig().vehicle_param();

  ComparableCost obstacle_cost;
  if (obs_sl_boundary.start_l() * obs_sl_boundary.end_l() <= 0.0) {
    return obstacle_cost;
  }

  const double adc_front_s = adc_s + vehicle_param.front_edge_to_center();
  const double adc_end_s = adc_s - vehicle_param.back_edge_to_center();
  const double adc_left_l = adc_l + vehicle_param.left_edge_to_center();
  const double adc_right_l = adc_l - vehicle_param.right_edge_to_center();

  if (adc_left_l + FLAGS_lateral_ignore_buffer < obs_sl_boundary.start_l() ||
      adc_right_l - FLAGS_lateral_ignore_buffer > obs_sl_boundary.end_l()) {
    return obstacle_cost;
  }

  bool no_overlap = ((adc_front_s < obs_sl_boundary.start_s() ||
                      adc_end_s > obs_sl_boundary.end_s()) ||  // longitudinal
                     (adc_left_l + 0.1 < obs_sl_boundary.start_l() ||
                      adc_right_l - 0.1 > obs_sl_boundary.end_l()));  // lateral

  if (!no_overlap) {
    obstacle_cost.cost_items[ComparableCost::HAS_COLLISION] = true;
  }

  // if obstacle is behind ADC, ignore its cost contribution.
  if (adc_front_s > obs_sl_boundary.end_s()) {
    return obstacle_cost;
  }

  const double delta_l = std::fmax(adc_right_l - obs_sl_boundary.end_l(),
                                   obs_sl_boundary.start_l() - adc_left_l);
  /*
  AWARN << "adc_s: " << adc_s << "; adc_left_l: " << adc_left_l
        << "; adc_right_l: " << adc_right_l << "; delta_l = " << delta_l;
  AWARN << obs_sl_boundary.ShortDebugString();
  */

  constexpr double kSafeDistance = 1.0;
  if (delta_l < kSafeDistance) {
    obstacle_cost.safety_cost +=
        config_.obstacle_collision_cost() *
        Sigmoid(config_.obstacle_collision_distance() - delta_l);
  }

  return obstacle_cost;
}

// Simple version: calculate obstacle cost by distance
ComparableCost TrajectoryCost::GetCostBetweenObsBoxes(
    const Box2d &ego_box, const Box2d &obstacle_box) const {
  ComparableCost obstacle_cost;

  const double distance = obstacle_box.DistanceTo(ego_box);
  if (distance > config_.obstacle_ignore_distance()) {
    return obstacle_cost;
  }

  obstacle_cost.safety_cost +=
      config_.obstacle_collision_cost() *
      Sigmoid(config_.obstacle_collision_distance() - distance);
  obstacle_cost.safety_cost +=
      20.0 * Sigmoid(config_.obstacle_risk_distance() - distance);
  return obstacle_cost;
}

Box2d TrajectoryCost::GetBoxFromSLPoint(const common::SLPoint &sl,
                                        const double dl) const {
  Vec2d xy_point;
  reference_line_->SLToXY(sl, &xy_point);

  ReferencePoint reference_point = reference_line_->GetReferencePoint(sl.s());

  const double one_minus_kappa_r_d = 1 - reference_point.kappa() * sl.l();
  const double delta_theta = std::atan2(dl, one_minus_kappa_r_d);
  const double theta =
      common::math::NormalizeAngle(delta_theta + reference_point.heading());
  return Box2d(xy_point, theta, vehicle_param_.length(),
               vehicle_param_.width());
}

// TODO(All): optimize obstacle cost calculation time
ComparableCost TrajectoryCost::Calculate(const QuinticPolynomialCurve1d &curve,
                                         const double start_s,
                                         const double end_s,
                                         const uint32_t curr_level,
                                         const uint32_t total_level) {
  ComparableCost total_cost;
  // path cost
  total_cost +=
      CalculatePathCost(curve, start_s, end_s, curr_level, total_level);

  // static obstacle cost
  total_cost += CalculateStaticObstacleCost(curve, start_s, end_s);

  // dynamic obstacle cost
  total_cost += CalculateDynamicObstacleCost(curve, start_s, end_s);
  return total_cost;
}

}  // namespace planning
}  // namespace apollo
<commit_msg>Planning: reduced the distance for cost calculation.<commit_after>/******************************************************************************
 * Copyright 2017 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

/**
 * @file
 **/

#include "modules/planning/toolkits/optimizers/road_graph/trajectory_cost.h"

#include <algorithm>
#include <cmath>
#include <limits>
#include <utility>

#include "modules/common/proto/pnc_point.pb.h"

#include "modules/common/configs/vehicle_config_helper.h"
#include "modules/common/math/vec2d.h"
#include "modules/common/util/util.h"
#include "modules/planning/common/planning_gflags.h"

namespace apollo {
namespace planning {

using apollo::common::TrajectoryPoint;
using apollo::common::math::Box2d;
using apollo::common::math::Sigmoid;
using apollo::common::math::Vec2d;

TrajectoryCost::TrajectoryCost(const DpPolyPathConfig &config,
                               const ReferenceLine &reference_line,
                               const bool is_change_lane_path,
                               const std::vector<const Obstacle *> &obstacles,
                               const common::VehicleParam &vehicle_param,
                               const SpeedData &heuristic_speed_data,
                               const common::SLPoint &init_sl_point,
                               const SLBoundary &adc_sl_boundary)
    : config_(config),
      reference_line_(&reference_line),
      is_change_lane_path_(is_change_lane_path),
      vehicle_param_(vehicle_param),
      heuristic_speed_data_(heuristic_speed_data),
      init_sl_point_(init_sl_point),
      adc_sl_boundary_(adc_sl_boundary) {
  const double total_time =
      std::min(heuristic_speed_data_.TotalTime(), FLAGS_prediction_total_time);

  num_of_time_stamps_ = static_cast<uint32_t>(
      std::floor(total_time / config.eval_time_interval()));

  for (const auto *ptr_obstacle : obstacles) {
    if (ptr_obstacle->IsIgnore()) {
      continue;
    } else if (ptr_obstacle->LongitudinalDecision().has_stop()) {
      continue;
    }
    const auto &sl_boundary = ptr_obstacle->PerceptionSLBoundary();

    const double adc_left_l =
        init_sl_point_.l() + vehicle_param_.left_edge_to_center();
    const double adc_right_l =
        init_sl_point_.l() - vehicle_param_.right_edge_to_center();

    if (adc_left_l + FLAGS_lateral_ignore_buffer < sl_boundary.start_l() ||
        adc_right_l - FLAGS_lateral_ignore_buffer > sl_boundary.end_l()) {
      continue;
    }

    bool is_bycycle_or_pedestrian =
        (ptr_obstacle->Perception().type() ==
             perception::PerceptionObstacle::BICYCLE ||
         ptr_obstacle->Perception().type() ==
             perception::PerceptionObstacle::PEDESTRIAN);

    if (ptr_obstacle->IsVirtual()) {
      // Virtual obstacle
      continue;
    } else if (ptr_obstacle->IsStatic() || is_bycycle_or_pedestrian) {
      static_obstacle_sl_boundaries_.push_back(std::move(sl_boundary));
    } else {
      std::vector<Box2d> box_by_time;
      for (uint32_t t = 0; t <= num_of_time_stamps_; ++t) {
        TrajectoryPoint trajectory_point =
            ptr_obstacle->GetPointAtTime(t * config.eval_time_interval());

        Box2d obstacle_box = ptr_obstacle->GetBoundingBox(trajectory_point);
        constexpr double kBuff = 0.5;
        Box2d expanded_obstacle_box =
            Box2d(obstacle_box.center(), obstacle_box.heading(),
                  obstacle_box.length() + kBuff, obstacle_box.width() + kBuff);
        box_by_time.push_back(expanded_obstacle_box);
      }
      dynamic_obstacle_boxes_.push_back(std::move(box_by_time));
    }
  }
}

ComparableCost TrajectoryCost::CalculatePathCost(
    const QuinticPolynomialCurve1d &curve, const double start_s,
    const double end_s, const uint32_t curr_level, const uint32_t total_level) {
  ComparableCost cost;
  double path_cost = 0.0;
  std::function<double(const double)> quasi_softmax = [this](const double x) {
    const double l0 = this->config_.path_l_cost_param_l0();
    const double b = this->config_.path_l_cost_param_b();
    const double k = this->config_.path_l_cost_param_k();
    return (b + std::exp(-k * (x - l0))) / (1.0 + std::exp(-k * (x - l0)));
  };

  for (double curve_s = 0.0; curve_s < (end_s - start_s);
       curve_s += config_.path_resolution()) {
    const double l = curve.Evaluate(0, curve_s);

    path_cost += l * l * config_.path_l_cost() * quasi_softmax(std::fabs(l));

    const double dl = std::fabs(curve.Evaluate(1, curve_s));
    if (IsOffRoad(curve_s + start_s, l, dl, is_change_lane_path_)) {
      cost.cost_items[ComparableCost::OUT_OF_BOUNDARY] = true;
    }

    path_cost += dl * dl * config_.path_dl_cost();

    const double ddl = std::fabs(curve.Evaluate(2, curve_s));
    path_cost += ddl * ddl * config_.path_ddl_cost();
  }
  path_cost *= config_.path_resolution();

  if (curr_level == total_level) {
    const double end_l = curve.Evaluate(0, end_s - start_s);
    path_cost +=
        std::sqrt(end_l - init_sl_point_.l() / 2.0) * config_.path_end_l_cost();
  }
  cost.smoothness_cost = path_cost;
  return cost;
}

bool TrajectoryCost::IsOffRoad(const double ref_s, const double l,
                               const double dl,
                               const bool is_change_lane_path) {
  constexpr double kIgnoreDistance = 5.0;
  if (ref_s - init_sl_point_.s() < kIgnoreDistance) {
    return false;
  }
  Vec2d rear_center(0.0, l);

  const auto &param = common::VehicleConfigHelper::GetConfig().vehicle_param();
  Vec2d vec_to_center(
      (param.front_edge_to_center() - param.back_edge_to_center()) / 2.0,
      (param.left_edge_to_center() - param.right_edge_to_center()) / 2.0);

  Vec2d rear_center_to_center = vec_to_center.rotate(std::atan(dl));
  Vec2d center = rear_center + rear_center_to_center;
  Vec2d front_center = center + rear_center_to_center;

  const double buffer = 0.1;  // in meters
  const double r_w =
      (param.left_edge_to_center() + param.right_edge_to_center()) / 2.0;
  const double r_l = param.back_edge_to_center();
  const double r = std::sqrt(r_w * r_w + r_l * r_l);

  double left_width = 0.0;
  double right_width = 0.0;
  reference_line_->GetLaneWidth(ref_s, &left_width, &right_width);

  double left_bound = std::max(init_sl_point_.l() + r + buffer, left_width);
  double right_bound = std::min(init_sl_point_.l() - r - buffer, -right_width);
  if (rear_center.y() + r + buffer / 2.0 > left_bound ||
      rear_center.y() - r - buffer / 2.0 < right_bound) {
    return true;
  }
  if (front_center.y() + r + buffer / 2.0 > left_bound ||
      front_center.y() - r - buffer / 2.0 < right_bound) {
    return true;
  }

  return false;
}

ComparableCost TrajectoryCost::CalculateStaticObstacleCost(
    const QuinticPolynomialCurve1d &curve, const double start_s,
    const double end_s) {
  ComparableCost obstacle_cost;
  for (double curr_s = start_s; curr_s <= end_s;
       curr_s += config_.path_resolution()) {
    const double curr_l = curve.Evaluate(0, curr_s - start_s);
    for (const auto &obs_sl_boundary : static_obstacle_sl_boundaries_) {
      obstacle_cost += GetCostFromObsSL(curr_s, curr_l, obs_sl_boundary);
    }
  }
  obstacle_cost.safety_cost *= config_.path_resolution();
  return obstacle_cost;
}

ComparableCost TrajectoryCost::CalculateDynamicObstacleCost(
    const QuinticPolynomialCurve1d &curve, const double start_s,
    const double end_s) const {
  ComparableCost obstacle_cost;
  if (dynamic_obstacle_boxes_.empty()) {
    return obstacle_cost;
  }

  double time_stamp = 0.0;
  for (size_t index = 0; index < num_of_time_stamps_;
       ++index, time_stamp += config_.eval_time_interval()) {
    common::SpeedPoint speed_point;
    heuristic_speed_data_.EvaluateByTime(time_stamp, &speed_point);
    double ref_s = speed_point.s() + init_sl_point_.s();
    if (ref_s < start_s) {
      continue;
    }
    if (ref_s > end_s) {
      break;
    }

    const double s = ref_s - start_s;  // s on spline curve
    const double l = curve.Evaluate(0, s);
    const double dl = curve.Evaluate(1, s);

    const common::SLPoint sl = common::util::MakeSLPoint(ref_s, l);
    const Box2d ego_box = GetBoxFromSLPoint(sl, dl);
    for (const auto &obstacle_trajectory : dynamic_obstacle_boxes_) {
      obstacle_cost +=
          GetCostBetweenObsBoxes(ego_box, obstacle_trajectory.at(index));
    }
  }
  constexpr double kDynamicObsWeight = 1e-6;
  obstacle_cost.safety_cost *=
      (config_.eval_time_interval() * kDynamicObsWeight);
  return obstacle_cost;
}

ComparableCost TrajectoryCost::GetCostFromObsSL(
    const double adc_s, const double adc_l, const SLBoundary &obs_sl_boundary) {
  const auto &vehicle_param =
      common::VehicleConfigHelper::Instance()->GetConfig().vehicle_param();

  ComparableCost obstacle_cost;
  if (obs_sl_boundary.start_l() * obs_sl_boundary.end_l() <= 0.0) {
    return obstacle_cost;
  }

  const double adc_front_s = adc_s + vehicle_param.front_edge_to_center();
  const double adc_end_s = adc_s - vehicle_param.back_edge_to_center();
  const double adc_left_l = adc_l + vehicle_param.left_edge_to_center();
  const double adc_right_l = adc_l - vehicle_param.right_edge_to_center();

  if (adc_left_l + FLAGS_lateral_ignore_buffer < obs_sl_boundary.start_l() ||
      adc_right_l - FLAGS_lateral_ignore_buffer > obs_sl_boundary.end_l()) {
    return obstacle_cost;
  }

  bool no_overlap = ((adc_front_s < obs_sl_boundary.start_s() ||
                      adc_end_s > obs_sl_boundary.end_s()) ||  // longitudinal
                     (adc_left_l + 0.1 < obs_sl_boundary.start_l() ||
                      adc_right_l - 0.1 > obs_sl_boundary.end_l()));  // lateral

  if (!no_overlap) {
    obstacle_cost.cost_items[ComparableCost::HAS_COLLISION] = true;
  }

  // if obstacle is behind ADC, ignore its cost contribution.
  if (adc_front_s > obs_sl_boundary.end_s()) {
    return obstacle_cost;
  }

  const double delta_l = std::fmax(adc_right_l - obs_sl_boundary.end_l(),
                                   obs_sl_boundary.start_l() - adc_left_l);
  /*
  AWARN << "adc_s: " << adc_s << "; adc_left_l: " << adc_left_l
        << "; adc_right_l: " << adc_right_l << "; delta_l = " << delta_l;
  AWARN << obs_sl_boundary.ShortDebugString();
  */

  constexpr double kSafeDistance = 0.6;
  if (delta_l < kSafeDistance) {
    obstacle_cost.safety_cost +=
        config_.obstacle_collision_cost() *
        Sigmoid(config_.obstacle_collision_distance() - delta_l);
  }

  return obstacle_cost;
}

// Simple version: calculate obstacle cost by distance
ComparableCost TrajectoryCost::GetCostBetweenObsBoxes(
    const Box2d &ego_box, const Box2d &obstacle_box) const {
  ComparableCost obstacle_cost;

  const double distance = obstacle_box.DistanceTo(ego_box);
  if (distance > config_.obstacle_ignore_distance()) {
    return obstacle_cost;
  }

  obstacle_cost.safety_cost +=
      config_.obstacle_collision_cost() *
      Sigmoid(config_.obstacle_collision_distance() - distance);
  obstacle_cost.safety_cost +=
      20.0 * Sigmoid(config_.obstacle_risk_distance() - distance);
  return obstacle_cost;
}

Box2d TrajectoryCost::GetBoxFromSLPoint(const common::SLPoint &sl,
                                        const double dl) const {
  Vec2d xy_point;
  reference_line_->SLToXY(sl, &xy_point);

  ReferencePoint reference_point = reference_line_->GetReferencePoint(sl.s());

  const double one_minus_kappa_r_d = 1 - reference_point.kappa() * sl.l();
  const double delta_theta = std::atan2(dl, one_minus_kappa_r_d);
  const double theta =
      common::math::NormalizeAngle(delta_theta + reference_point.heading());
  return Box2d(xy_point, theta, vehicle_param_.length(),
               vehicle_param_.width());
}

// TODO(All): optimize obstacle cost calculation time
ComparableCost TrajectoryCost::Calculate(const QuinticPolynomialCurve1d &curve,
                                         const double start_s,
                                         const double end_s,
                                         const uint32_t curr_level,
                                         const uint32_t total_level) {
  ComparableCost total_cost;
  // path cost
  total_cost +=
      CalculatePathCost(curve, start_s, end_s, curr_level, total_level);

  // static obstacle cost
  total_cost += CalculateStaticObstacleCost(curve, start_s, end_s);

  // dynamic obstacle cost
  total_cost += CalculateDynamicObstacleCost(curve, start_s, end_s);
  return total_cost;
}

}  // namespace planning
}  // namespace apollo
<|endoftext|>


<commit_before>// Include the defined classes that are to be exported to python
#include "IntegratorHPMC.h"
#include "IntegratorHPMCMono.h"
#include "IntegratorHPMCMono_FL.h"

#include "ShapeSphere.h"
#include "ShapeConvexPolygon.h"
#include "ShapePolyhedron.h"
#include "ShapeConvexPolyhedron.h"
#include "ShapeSpheropolyhedron.h"
#include "ShapeSpheropolygon.h"
#include "ShapeSimplePolygon.h"
#include "ShapeEllipsoid.h"
#include "ShapeFacetedSphere.h"
#include "ShapeSphinx.h"
#include "ShapeUnion.h"
#include "AnalyzerSDF.h"
#include "UpdaterBoxNPT.h"

#ifdef ENABLE_CUDA
#include "IntegratorHPMCMonoGPU.h"
#include "IntegratorHPMCMonoImplicitGPU.h"
#endif

/*! \file module.cc
    \brief Export classes to python
*/

// Include boost.python to do the exporting
#include <boost/python.hpp>

using namespace boost::python;
using namespace hpmc;

using namespace hpmc::detail;

namespace hpmc
{

//! Export the GPU integrators
void export_hpmc_gpu()
    {
    #ifdef ENABLE_CUDA
    export_IntegratorHPMCMonoGPU< ShapeSphere >("IntegratorHPMCMonoGPUSphere");
    export_IntegratorHPMCMonoGPU< ShapeUnion<ShapeSphere> >("IntegratorHPMCMonoGPUSphereUnion");
    export_IntegratorHPMCMonoGPU< ShapeConvexPolygon >("IntegratorHPMCMonoGPUConvexPolygon");
    export_IntegratorHPMCMonoGPU< ShapeSimplePolygon >("IntegratorHPMCMonoGPUSimplePolygon");
    export_IntegratorHPMCMonoGPU< ShapePolyhedron >("IntegratorHPMCMonoGPUPolyhedron");
    export_IntegratorHPMCMonoGPU< ShapeConvexPolyhedron<8> >("IntegratorHPMCMonoGPUConvexPolyhedron8");
    export_IntegratorHPMCMonoGPU< ShapeConvexPolyhedron<16> >("IntegratorHPMCMonoGPUConvexPolyhedron16");
    export_IntegratorHPMCMonoGPU< ShapeConvexPolyhedron<32> >("IntegratorHPMCMonoGPUConvexPolyhedron32");
    export_IntegratorHPMCMonoGPU< ShapeConvexPolyhedron<64> >("IntegratorHPMCMonoGPUConvexPolyhedron64");
    export_IntegratorHPMCMonoGPU< ShapeConvexPolyhedron<128> >("IntegratorHPMCMonoGPUConvexPolyhedron128");
    export_IntegratorHPMCMonoGPU< ShapeSpheropolyhedron<8> >("IntegratorHPMCMonoGPUSpheropolyhedron8");
    export_IntegratorHPMCMonoGPU< ShapeSpheropolyhedron<16> >("IntegratorHPMCMonoGPUSpheropolyhedron16");
    export_IntegratorHPMCMonoGPU< ShapeSpheropolyhedron<32> >("IntegratorHPMCMonoGPUSpheropolyhedron32");
    export_IntegratorHPMCMonoGPU< ShapeSpheropolyhedron<64> >("IntegratorHPMCMonoGPUSpheropolyhedron64");
    export_IntegratorHPMCMonoGPU< ShapeSpheropolyhedron<128> >("IntegratorHPMCMonoGPUSpheropolyhedron128");
    export_IntegratorHPMCMonoGPU< ShapeEllipsoid >("IntegratorHPMCMonoGPUEllipsoid");
    export_IntegratorHPMCMonoGPU< ShapeSpheropolygon >("IntegratorHPMCMonoGPUSpheropolygon");
    export_IntegratorHPMCMonoGPU< ShapeFacetedSphere >("IntegratorHPMCMonoGPUFacetedSphere");
    #ifdef ENABLE_SPHINX_GPU
    export_IntegratorHPMCMonoGPU< ShapeSphinx >("IntegratorHPMCMonoGPUSphinx");
    #endif

    export_IntegratorHPMCMonoImplicitGPU< ShapeSphere >("IntegratorHPMCMonoImplicitGPUSphere");
    export_IntegratorHPMCMonoImplicitGPU< ShapeConvexPolygon >("IntegratorHPMCMonoImplicitGPUConvexPolygon");
    export_IntegratorHPMCMonoImplicitGPU< ShapeSimplePolygon >("IntegratorHPMCMonoImplicitGPUSimplePolygon");
    export_IntegratorHPMCMonoImplicitGPU< ShapePolyhedron >("IntegratorHPMCMonoImplicitGPUPolyhedron");
    export_IntegratorHPMCMonoImplicitGPU< ShapeConvexPolyhedron<8> >("IntegratorHPMCMonoImplicitGPUConvexPolyhedron8");
    export_IntegratorHPMCMonoImplicitGPU< ShapeConvexPolyhedron<16> >("IntegratorHPMCMonoImplicitGPUConvexPolyhedron16");
    export_IntegratorHPMCMonoImplicitGPU< ShapeConvexPolyhedron<32> >("IntegratorHPMCMonoImplicitGPUConvexPolyhedron32");
    export_IntegratorHPMCMonoImplicitGPU< ShapeConvexPolyhedron<64> >("IntegratorHPMCMonoImplicitGPUConvexPolyhedron64");
    export_IntegratorHPMCMonoImplicitGPU< ShapeConvexPolyhedron<128> >("IntegratorHPMCMonoImplicitGPUConvexPolyhedron128");
    export_IntegratorHPMCMonoImplicitGPU< ShapeSpheropolyhedron<8> >("IntegratorHPMCMonoImplicitGPUSpheropolyhedron8");
    export_IntegratorHPMCMonoImplicitGPU< ShapeSpheropolyhedron<16> >("IntegratorHPMCMonoImplicitGPUSpheropolyhedron16");
    export_IntegratorHPMCMonoImplicitGPU< ShapeSpheropolyhedron<32> >("IntegratorHPMCMonoImplicitGPUSpheropolyhedron32");
    export_IntegratorHPMCMonoImplicitGPU< ShapeSpheropolyhedron<64> >("IntegratorHPMCMonoImplicitGPUSpheropolyhedron64");
    export_IntegratorHPMCMonoImplicitGPU< ShapeSpheropolyhedron<128> >("IntegratorHPMCMonoImplicitGPUSpheropolyhedron128");
    export_IntegratorHPMCMonoImplicitGPU< ShapeEllipsoid>("IntegratorHPMCMonoImplicitGPUEllipsoid");
    export_IntegratorHPMCMonoImplicitGPU< ShapeSpheropolygon>("IntegratorHPMCMonoImplicitGPUSpheropolygon");
    export_IntegratorHPMCMonoImplicitGPU< ShapeFacetedSphere>("IntegratorHPMCMonoImplicitGPUFacetedSphere");
    #ifdef ENABLE_SPHINX_GPU
    export_IntegratorHPMCMonoImplicitGPU< ShapeSphinx >("IntegratorHPMCMonoImplicitGPUSphinx");
    #endif

    #endif
    }
}
<commit_msg>export sphere_union implicit integrator on GPU<commit_after>// Include the defined classes that are to be exported to python
#include "IntegratorHPMC.h"
#include "IntegratorHPMCMono.h"
#include "IntegratorHPMCMono_FL.h"

#include "ShapeSphere.h"
#include "ShapeConvexPolygon.h"
#include "ShapePolyhedron.h"
#include "ShapeConvexPolyhedron.h"
#include "ShapeSpheropolyhedron.h"
#include "ShapeSpheropolygon.h"
#include "ShapeSimplePolygon.h"
#include "ShapeEllipsoid.h"
#include "ShapeFacetedSphere.h"
#include "ShapeSphinx.h"
#include "ShapeUnion.h"
#include "AnalyzerSDF.h"
#include "UpdaterBoxNPT.h"

#ifdef ENABLE_CUDA
#include "IntegratorHPMCMonoGPU.h"
#include "IntegratorHPMCMonoImplicitGPU.h"
#endif

/*! \file module.cc
    \brief Export classes to python
*/

// Include boost.python to do the exporting
#include <boost/python.hpp>

using namespace boost::python;
using namespace hpmc;

using namespace hpmc::detail;

namespace hpmc
{

//! Export the GPU integrators
void export_hpmc_gpu()
    {
    #ifdef ENABLE_CUDA
    export_IntegratorHPMCMonoGPU< ShapeSphere >("IntegratorHPMCMonoGPUSphere");
    export_IntegratorHPMCMonoGPU< ShapeUnion<ShapeSphere> >("IntegratorHPMCMonoGPUSphereUnion");
    export_IntegratorHPMCMonoGPU< ShapeConvexPolygon >("IntegratorHPMCMonoGPUConvexPolygon");
    export_IntegratorHPMCMonoGPU< ShapeSimplePolygon >("IntegratorHPMCMonoGPUSimplePolygon");
    export_IntegratorHPMCMonoGPU< ShapePolyhedron >("IntegratorHPMCMonoGPUPolyhedron");
    export_IntegratorHPMCMonoGPU< ShapeConvexPolyhedron<8> >("IntegratorHPMCMonoGPUConvexPolyhedron8");
    export_IntegratorHPMCMonoGPU< ShapeConvexPolyhedron<16> >("IntegratorHPMCMonoGPUConvexPolyhedron16");
    export_IntegratorHPMCMonoGPU< ShapeConvexPolyhedron<32> >("IntegratorHPMCMonoGPUConvexPolyhedron32");
    export_IntegratorHPMCMonoGPU< ShapeConvexPolyhedron<64> >("IntegratorHPMCMonoGPUConvexPolyhedron64");
    export_IntegratorHPMCMonoGPU< ShapeConvexPolyhedron<128> >("IntegratorHPMCMonoGPUConvexPolyhedron128");
    export_IntegratorHPMCMonoGPU< ShapeSpheropolyhedron<8> >("IntegratorHPMCMonoGPUSpheropolyhedron8");
    export_IntegratorHPMCMonoGPU< ShapeSpheropolyhedron<16> >("IntegratorHPMCMonoGPUSpheropolyhedron16");
    export_IntegratorHPMCMonoGPU< ShapeSpheropolyhedron<32> >("IntegratorHPMCMonoGPUSpheropolyhedron32");
    export_IntegratorHPMCMonoGPU< ShapeSpheropolyhedron<64> >("IntegratorHPMCMonoGPUSpheropolyhedron64");
    export_IntegratorHPMCMonoGPU< ShapeSpheropolyhedron<128> >("IntegratorHPMCMonoGPUSpheropolyhedron128");
    export_IntegratorHPMCMonoGPU< ShapeEllipsoid >("IntegratorHPMCMonoGPUEllipsoid");
    export_IntegratorHPMCMonoGPU< ShapeSpheropolygon >("IntegratorHPMCMonoGPUSpheropolygon");
    export_IntegratorHPMCMonoGPU< ShapeFacetedSphere >("IntegratorHPMCMonoGPUFacetedSphere");
    #ifdef ENABLE_SPHINX_GPU
    export_IntegratorHPMCMonoGPU< ShapeSphinx >("IntegratorHPMCMonoGPUSphinx");
    #endif

    export_IntegratorHPMCMonoImplicitGPU< ShapeSphere >("IntegratorHPMCMonoImplicitGPUSphere");
    export_IntegratorHPMCMonoImplicitGPU< ShapeUnion<ShapeSphere> >("IntegratorHPMCMonoImplicitGPUSphereUnion");
    export_IntegratorHPMCMonoImplicitGPU< ShapeConvexPolygon >("IntegratorHPMCMonoImplicitGPUConvexPolygon");
    export_IntegratorHPMCMonoImplicitGPU< ShapeSimplePolygon >("IntegratorHPMCMonoImplicitGPUSimplePolygon");
    export_IntegratorHPMCMonoImplicitGPU< ShapePolyhedron >("IntegratorHPMCMonoImplicitGPUPolyhedron");
    export_IntegratorHPMCMonoImplicitGPU< ShapeConvexPolyhedron<8> >("IntegratorHPMCMonoImplicitGPUConvexPolyhedron8");
    export_IntegratorHPMCMonoImplicitGPU< ShapeConvexPolyhedron<16> >("IntegratorHPMCMonoImplicitGPUConvexPolyhedron16");
    export_IntegratorHPMCMonoImplicitGPU< ShapeConvexPolyhedron<32> >("IntegratorHPMCMonoImplicitGPUConvexPolyhedron32");
    export_IntegratorHPMCMonoImplicitGPU< ShapeConvexPolyhedron<64> >("IntegratorHPMCMonoImplicitGPUConvexPolyhedron64");
    export_IntegratorHPMCMonoImplicitGPU< ShapeConvexPolyhedron<128> >("IntegratorHPMCMonoImplicitGPUConvexPolyhedron128");
    export_IntegratorHPMCMonoImplicitGPU< ShapeSpheropolyhedron<8> >("IntegratorHPMCMonoImplicitGPUSpheropolyhedron8");
    export_IntegratorHPMCMonoImplicitGPU< ShapeSpheropolyhedron<16> >("IntegratorHPMCMonoImplicitGPUSpheropolyhedron16");
    export_IntegratorHPMCMonoImplicitGPU< ShapeSpheropolyhedron<32> >("IntegratorHPMCMonoImplicitGPUSpheropolyhedron32");
    export_IntegratorHPMCMonoImplicitGPU< ShapeSpheropolyhedron<64> >("IntegratorHPMCMonoImplicitGPUSpheropolyhedron64");
    export_IntegratorHPMCMonoImplicitGPU< ShapeSpheropolyhedron<128> >("IntegratorHPMCMonoImplicitGPUSpheropolyhedron128");
    export_IntegratorHPMCMonoImplicitGPU< ShapeEllipsoid>("IntegratorHPMCMonoImplicitGPUEllipsoid");
    export_IntegratorHPMCMonoImplicitGPU< ShapeSpheropolygon>("IntegratorHPMCMonoImplicitGPUSpheropolygon");
    export_IntegratorHPMCMonoImplicitGPU< ShapeFacetedSphere>("IntegratorHPMCMonoImplicitGPUFacetedSphere");
    #ifdef ENABLE_SPHINX_GPU
    export_IntegratorHPMCMonoImplicitGPU< ShapeSphinx >("IntegratorHPMCMonoImplicitGPUSphinx");
    #endif

    #endif
    }
}
<|endoftext|>


<commit_before>/*
 * Thread.cpp  15.08.2006 (mueller)
 *
 * Copyright (C) 2006 by Universitaet Stuttgart (VIS). Alle Rechte vorbehalten.
 */

#include "vislib/Thread.h"

#ifndef _WIN32
#include <unistd.h>
#endif /* !_WIN32 */

#include "vislib/assert.h"
#include "vislib/error.h"
#include "vislib/IllegalParamException.h"
#include "vislib/IllegalStateException.h"
#include "vislib/SystemException.h"
#include "vislib/Trace.h"
#include "vislib/UnsupportedOperationException.h"

#include "DynamicFunctionPointer.h"

#include <cstdio>
#include <iostream>

#ifndef _WIN32
/**
 * Return code that marks a thread as still running. Make sure that the value
 * is the same as on Windows.
 */
#define STILL_ACTIVE (259)
#endif /* !_WIN32 */

/*
 * vislib::sys::Thread::Sleep
 */
void vislib::sys::Thread::Sleep(const DWORD millis) {
#ifdef _WIN32
    ::Sleep(millis);
#else /* _WIN32 */
    if (millis >= 1000) {
        /* At least one second to sleep. Use ::sleep() for full seconds. */
        ::sleep(millis / 1000);
    }

    ::usleep((millis % 1000) * 1000);
#endif /* _WIN32 */
}

/*
 * vislib::sys::Thread::Reschedule
 */
void vislib::sys::Thread::Reschedule(void) {
#ifdef _WIN32
#if (_WIN32_WINNT >= 0x0400)
    ::SwitchToThread();
#else
    DynamicFunctionPointer<BOOL (*)(void)> stt("kernel32", "SwitchToThread");
    if (stt.IsValid()) {
        stt();
    } else {
        ::Sleep(0);
    }
#endif
#else /* _WIN32 */
    if (::sched_yield() != 0) {
        throw SystemException(__FILE__, __LINE__);
    }
#endif /* _WIN32 */
}

/*
 * vislib::sys::Thread::Thread
 */
vislib::sys::Thread::Thread(Runnable *runnable)
        : id(0), runnable(runnable), runnableFunc(NULL) {
#ifdef _WIN32
    this->handle = NULL;

#else /* _WIN32 */
    ::pthread_attr_init(&this->attribs);
    ::pthread_attr_setscope(&this->attribs, PTHREAD_SCOPE_SYSTEM);
    ::pthread_attr_setdetachstate(&this->attribs, PTHREAD_CREATE_JOINABLE);

    this->exitCode = 0;

#endif /* _WIN32 */

    this->threadFuncParam.thread = this;
    this->threadFuncParam.userData = NULL;
}

/*
 * vislib::sys::Thread::Thread
 */
vislib::sys::Thread::Thread(Runnable::Function runnableFunc)
        : id(0), runnable(NULL), runnableFunc(runnableFunc) {
#ifdef _WIN32
    this->handle = NULL;

#else /* _WIN32 */
    ::pthread_attr_init(&this->attribs);
    ::pthread_attr_setscope(&this->attribs, PTHREAD_SCOPE_SYSTEM);
    ::pthread_attr_setdetachstate(&this->attribs, PTHREAD_CREATE_JOINABLE);

    this->exitCode = 0;

#endif /* _WIN32 */

    this->threadFuncParam.thread = this;
    this->threadFuncParam.userData = NULL;
}

/*
 * vislib::sys::Thread::~Thread
 */
vislib::sys::Thread::~Thread(void) {
#ifdef _WIN32
    if (this->handle != NULL) {
        ::CloseHandle(this->handle);
    }

#else /* _WIIN32 */
    // TODO: Dirty hack, don't know whether this is always working.
    if (this->id != 0) {
        ::pthread_detach(this->id);
        ::pthread_attr_destroy(&this->attribs);
    }

#endif /* _WIN32 */
}

/*
 * vislib::sys::Thread::GetExitCode
 */
DWORD vislib::sys::Thread::GetExitCode(void) const {
#ifdef _WIN32
    DWORD retval = 0;
    if (::GetExitCodeThread(this->handle, &retval) == FALSE) {
        throw SystemException(__FILE__, __LINE__);
    }

    return retval;

#else /* _WIN32 */
    return this->exitCode;
#endif /* _WIN32 */
}

/*
 * vislib::sys::Thread::IsRunning
 */
bool vislib::sys::Thread::IsRunning(void) const {
    try {
        return (this->GetExitCode() == STILL_ACTIVE);
    } catch (SystemException) {
        return false;
    }
}

/*
 * vislib::sys::Thread::Join
 */
void vislib::sys::Thread::Join(void) {
#ifdef _WIN32
    if (this->handle != NULL) {
        if (::WaitForSingleObject(this->handle, INFINITE) == WAIT_FAILED) {
            throw SystemException(__FILE__, __LINE__);
        }
    }

#else /* _WIN32 */
    if (this->id != 0) {
        if (::pthread_join(this->id, NULL) != 0) {
            throw SystemException(__FILE__, __LINE__);
        }
    }

#endif /* _WIN32 */
}

/*
 * vislib::sys::Thread::Start
 */
bool vislib::sys::Thread::Start(void *userData) {
    if (this->IsRunning()) {
        /*
         * The thread must not be started twice at the same time as this would
         * leave unclosed handles.
         */
        return false;
    }

    /* Set the user data. */
    this->threadFuncParam.userData = userData;

#ifdef _WIN32
    /* Close possible old handle. */
    if (this->handle != NULL) {
        ::CloseHandle(this->handle);
    }

    if ((this->handle = ::CreateThread(NULL, 0, Thread::ThreadFunc,
            &this->threadFuncParam, 0, &this->id)) != NULL) {
        return true;

    } else {
        VLTRACE(Trace::LEVEL_VL_ERROR, "CreateThread() failed with error %d.\n",
            ::GetLastError());
        throw SystemException(__FILE__, __LINE__);
    }

#else /* _WIN32 */
    if (::pthread_create(&this->id, &this->attribs, Thread::ThreadFunc,
            static_cast<void *>(&this->threadFuncParam)) == 0) {
        this->exitCode = STILL_ACTIVE;  // Mark thread as running.
        return true;

    } else {
        VLTRACE(Trace::LEVEL_VL_ERROR, "pthread_create() failed with error %d.\n",
            ::GetLastError());
        throw SystemException(__FILE__, __LINE__);
    }
#endif /* _WIN32 */
}

/*
 * vislib::sys::Thread::Terminate
 */
bool vislib::sys::Thread::Terminate(const bool forceTerminate,
                                    const int exitCode) {
    ASSERT(exitCode != STILL_ACTIVE);   // User should never set this.

    if (forceTerminate) {
        /* Force immediate termination of the thread. */

#ifdef _WIN32
        if (::TerminateThread(this->handle, exitCode) == FALSE) {
            VLTRACE(Trace::LEVEL_VL_ERROR, "TerminateThread() failed with error "
                "%d.\n", ::GetLastError());
            throw SystemException(__FILE__, __LINE__);
        }

        return true;

#else /* _WIN32 */
        this->exitCode = exitCode;

        if (::pthread_cancel(this->id) != 0) {
            VLTRACE(Trace::LEVEL_VL_ERROR, "pthread_cancel() failed with error "
                "%d.\n", ::GetLastError());
            throw SystemException(__FILE__, __LINE__);
        }

        return true;
#endif /* _WIN32 */

    } else {
        return this->TryTerminate(true);
    } /* end if (forceTerminate) */
}

/*
 * vislib::sys::Thread::TryTerminate
 */
bool vislib::sys::Thread::TryTerminate(const bool doWait) {

    if (this->runnable == NULL) {
        throw IllegalStateException("TryTerminate can only be used, if the "
            "thread is using a Runnable.", __FILE__, __LINE__);
    }
    ASSERT(this->runnable != NULL);

    if (this->runnable->Terminate()) {
        /*
         * Wait for thread to finish, if Runnable acknowledged and waiting was
         * requested.
         */
        if (doWait) {
            this->Join();
        }

        return true;

    } else {
        /* Runnable did not acknowledge. */
        return false;
    }
}

#ifndef _WIN32
/*
 * vislib::sys::Thread::CleanupFunc
 */
void vislib::sys::Thread::CleanupFunc(void *param) {
    ASSERT(param != NULL);

    Thread *t = static_cast<Thread *>(param);

    /*
     * In case the thread has still an exit code of STILL_ACTIVE, set a new one
     * to mark the thread as finished.
     */
    if (t->exitCode == STILL_ACTIVE) {
        VLTRACE(Trace::LEVEL_VL_WARN, "CleanupFunc called with exit code "
            "STILL_ACTIVE");
        t->exitCode = 0;
    }
}
#endif /* !_WIN32 */

/*
 * vislib::sys::Thread::ThreadFunc
 */
#ifdef _WIN32
DWORD WINAPI vislib::sys::Thread::ThreadFunc(void *param) {
#else /* _WIN32 */
void *vislib::sys::Thread::ThreadFunc(void *param) {
#endif /* _WIN32 */
    ASSERT(param != NULL);

    int retval = 0;
    ThreadFuncParam *tfp = static_cast<ThreadFuncParam *>(param);
    Thread *t = tfp->thread;
    ASSERT(t != NULL);

#ifndef _WIN32
    pthread_cleanup_push(Thread::CleanupFunc, t);
#endif /* !_WIN32 */

    if (t->runnable != NULL) {
        retval = t->runnable->Run(tfp->userData);
    } else {
        ASSERT(t->runnableFunc != NULL);
        retval = t->runnableFunc(tfp->userData);
    }
    ASSERT(retval != STILL_ACTIVE); // Thread should never use STILL_ACTIVE!

#ifndef _WIN32
    t->exitCode = retval;
    pthread_cleanup_pop(1);
#endif /* !_WIN32 */

    VLTRACE(Trace::LEVEL_VL_INFO, "Thread [%u] has exited with code %d (0x%x).\n",
        t->id, retval, retval);

#ifdef _WIN32
    return static_cast<DWORD>(retval);
#else /* _WIN32 */
    return reinterpret_cast<void *>(retval);
#endif /* _WIN32 */
}

/*
 * vislib::sys::Thread::Thread
 */
vislib::sys::Thread::Thread(const Thread& rhs) {
    throw UnsupportedOperationException("vislib::sys::Thread::Thread",
        __FILE__, __LINE__);
}

/*
 * vislib::sys::Thread::operator =
 */
vislib::sys::Thread& vislib::sys::Thread::operator =(const Thread& rhs) {
    if (this != &rhs) {
        throw IllegalParamException("rhs_", __FILE__, __LINE__);
    }

    return *this;
}
<commit_msg>Added an additional test to Thread::IsRunning to fix a weird behavior.<commit_after>/*
 * Thread.cpp  15.08.2006 (mueller)
 *
 * Copyright (C) 2006 by Universitaet Stuttgart (VIS). Alle Rechte vorbehalten.
 */

#include "vislib/Thread.h"

#ifndef _WIN32
#include <unistd.h>
#endif /* !_WIN32 */

#include "vislib/assert.h"
#include "vislib/error.h"
#include "vislib/IllegalParamException.h"
#include "vislib/IllegalStateException.h"
#include "vislib/SystemException.h"
#include "vislib/Trace.h"
#include "vislib/UnsupportedOperationException.h"

#include "DynamicFunctionPointer.h"

#include <cstdio>
#include <iostream>

#ifndef _WIN32
/**
 * Return code that marks a thread as still running. Make sure that the value
 * is the same as on Windows.
 */
#define STILL_ACTIVE (259)
#endif /* !_WIN32 */

/*
 * vislib::sys::Thread::Sleep
 */
void vislib::sys::Thread::Sleep(const DWORD millis) {
#ifdef _WIN32
    ::Sleep(millis);
#else /* _WIN32 */
    if (millis >= 1000) {
        /* At least one second to sleep. Use ::sleep() for full seconds. */
        ::sleep(millis / 1000);
    }

    ::usleep((millis % 1000) * 1000);
#endif /* _WIN32 */
}

/*
 * vislib::sys::Thread::Reschedule
 */
void vislib::sys::Thread::Reschedule(void) {
#ifdef _WIN32
#if (_WIN32_WINNT >= 0x0400)
    ::SwitchToThread();
#else
    DynamicFunctionPointer<BOOL (*)(void)> stt("kernel32", "SwitchToThread");
    if (stt.IsValid()) {
        stt();
    } else {
        ::Sleep(0);
    }
#endif
#else /* _WIN32 */
    if (::sched_yield() != 0) {
        throw SystemException(__FILE__, __LINE__);
    }
#endif /* _WIN32 */
}

/*
 * vislib::sys::Thread::Thread
 */
vislib::sys::Thread::Thread(Runnable *runnable)
        : id(0), runnable(runnable), runnableFunc(NULL) {
#ifdef _WIN32
    this->handle = NULL;

#else /* _WIN32 */
    ::pthread_attr_init(&this->attribs);
    ::pthread_attr_setscope(&this->attribs, PTHREAD_SCOPE_SYSTEM);
    ::pthread_attr_setdetachstate(&this->attribs, PTHREAD_CREATE_JOINABLE);

    this->exitCode = 0;

#endif /* _WIN32 */

    this->threadFuncParam.thread = this;
    this->threadFuncParam.userData = NULL;
}

/*
 * vislib::sys::Thread::Thread
 */
vislib::sys::Thread::Thread(Runnable::Function runnableFunc)
        : id(0), runnable(NULL), runnableFunc(runnableFunc) {
#ifdef _WIN32
    this->handle = NULL;

#else /* _WIN32 */
    ::pthread_attr_init(&this->attribs);
    ::pthread_attr_setscope(&this->attribs, PTHREAD_SCOPE_SYSTEM);
    ::pthread_attr_setdetachstate(&this->attribs, PTHREAD_CREATE_JOINABLE);

    this->exitCode = 0;

#endif /* _WIN32 */

    this->threadFuncParam.thread = this;
    this->threadFuncParam.userData = NULL;
}

/*
 * vislib::sys::Thread::~Thread
 */
vislib::sys::Thread::~Thread(void) {
#ifdef _WIN32
    if (this->handle != NULL) {
        ::CloseHandle(this->handle);
    }

#else /* _WIIN32 */
    // TODO: Dirty hack, don't know whether this is always working.
    if (this->id != 0) {
        ::pthread_detach(this->id);
        ::pthread_attr_destroy(&this->attribs);
    }

#endif /* _WIN32 */
}

/*
 * vislib::sys::Thread::GetExitCode
 */
DWORD vislib::sys::Thread::GetExitCode(void) const {
#ifdef _WIN32
    DWORD retval = 0;
    if (::GetExitCodeThread(this->handle, &retval) == FALSE) {
        throw SystemException(__FILE__, __LINE__);
    }

    return retval;

#else /* _WIN32 */
    return this->exitCode;
#endif /* _WIN32 */
}

/*
 * vislib::sys::Thread::IsRunning
 */
bool vislib::sys::Thread::IsRunning(void) const {
    try {
        return ((this->handle != NULL)
            && (this->GetExitCode() == STILL_ACTIVE));
    } catch (SystemException) {
        return false;
    }
}

/*
 * vislib::sys::Thread::Join
 */
void vislib::sys::Thread::Join(void) {
#ifdef _WIN32
    if (this->handle != NULL) {
        if (::WaitForSingleObject(this->handle, INFINITE) == WAIT_FAILED) {
            throw SystemException(__FILE__, __LINE__);
        }
    }

#else /* _WIN32 */
    if (this->id != 0) {
        if (::pthread_join(this->id, NULL) != 0) {
            throw SystemException(__FILE__, __LINE__);
        }
    }

#endif /* _WIN32 */
}

/*
 * vislib::sys::Thread::Start
 */
bool vislib::sys::Thread::Start(void *userData) {
    if (this->IsRunning()) {
        /*
         * The thread must not be started twice at the same time as this would
         * leave unclosed handles.
         */
        return false;
    }

    /* Set the user data. */
    this->threadFuncParam.userData = userData;

#ifdef _WIN32
    /* Close possible old handle. */
    if (this->handle != NULL) {
        ::CloseHandle(this->handle);
    }

    if ((this->handle = ::CreateThread(NULL, 0, Thread::ThreadFunc,
            &this->threadFuncParam, 0, &this->id)) != NULL) {
        return true;

    } else {
        VLTRACE(Trace::LEVEL_VL_ERROR, "CreateThread() failed with error %d.\n",
            ::GetLastError());
        throw SystemException(__FILE__, __LINE__);
    }

#else /* _WIN32 */
    if (::pthread_create(&this->id, &this->attribs, Thread::ThreadFunc,
            static_cast<void *>(&this->threadFuncParam)) == 0) {
        this->exitCode = STILL_ACTIVE;  // Mark thread as running.
        return true;

    } else {
        VLTRACE(Trace::LEVEL_VL_ERROR, "pthread_create() failed with error %d.\n",
            ::GetLastError());
        throw SystemException(__FILE__, __LINE__);
    }
#endif /* _WIN32 */
}

/*
 * vislib::sys::Thread::Terminate
 */
bool vislib::sys::Thread::Terminate(const bool forceTerminate,
                                    const int exitCode) {
    ASSERT(exitCode != STILL_ACTIVE);   // User should never set this.

    if (forceTerminate) {
        /* Force immediate termination of the thread. */

#ifdef _WIN32
        if (::TerminateThread(this->handle, exitCode) == FALSE) {
            VLTRACE(Trace::LEVEL_VL_ERROR, "TerminateThread() failed with error "
                "%d.\n", ::GetLastError());
            throw SystemException(__FILE__, __LINE__);
        }

        return true;

#else /* _WIN32 */
        this->exitCode = exitCode;

        if (::pthread_cancel(this->id) != 0) {
            VLTRACE(Trace::LEVEL_VL_ERROR, "pthread_cancel() failed with error "
                "%d.\n", ::GetLastError());
            throw SystemException(__FILE__, __LINE__);
        }

        return true;
#endif /* _WIN32 */

    } else {
        return this->TryTerminate(true);
    } /* end if (forceTerminate) */
}

/*
 * vislib::sys::Thread::TryTerminate
 */
bool vislib::sys::Thread::TryTerminate(const bool doWait) {

    if (this->runnable == NULL) {
        throw IllegalStateException("TryTerminate can only be used, if the "
            "thread is using a Runnable.", __FILE__, __LINE__);
    }
    ASSERT(this->runnable != NULL);

    if (this->runnable->Terminate()) {
        /*
         * Wait for thread to finish, if Runnable acknowledged and waiting was
         * requested.
         */
        if (doWait) {
            this->Join();
        }

        return true;

    } else {
        /* Runnable did not acknowledge. */
        return false;
    }
}

#ifndef _WIN32
/*
 * vislib::sys::Thread::CleanupFunc
 */
void vislib::sys::Thread::CleanupFunc(void *param) {
    ASSERT(param != NULL);

    Thread *t = static_cast<Thread *>(param);

    /*
     * In case the thread has still an exit code of STILL_ACTIVE, set a new one
     * to mark the thread as finished.
     */
    if (t->exitCode == STILL_ACTIVE) {
        VLTRACE(Trace::LEVEL_VL_WARN, "CleanupFunc called with exit code "
            "STILL_ACTIVE");
        t->exitCode = 0;
    }
}
#endif /* !_WIN32 */

/*
 * vislib::sys::Thread::ThreadFunc
 */
#ifdef _WIN32
DWORD WINAPI vislib::sys::Thread::ThreadFunc(void *param) {
#else /* _WIN32 */
void *vislib::sys::Thread::ThreadFunc(void *param) {
#endif /* _WIN32 */
    ASSERT(param != NULL);

    int retval = 0;
    ThreadFuncParam *tfp = static_cast<ThreadFuncParam *>(param);
    Thread *t = tfp->thread;
    ASSERT(t != NULL);

#ifndef _WIN32
    pthread_cleanup_push(Thread::CleanupFunc, t);
#endif /* !_WIN32 */

    if (t->runnable != NULL) {
        retval = t->runnable->Run(tfp->userData);
    } else {
        ASSERT(t->runnableFunc != NULL);
        retval = t->runnableFunc(tfp->userData);
    }
    ASSERT(retval != STILL_ACTIVE); // Thread should never use STILL_ACTIVE!

#ifndef _WIN32
    t->exitCode = retval;
    pthread_cleanup_pop(1);
#endif /* !_WIN32 */

    VLTRACE(Trace::LEVEL_VL_INFO, "Thread [%u] has exited with code %d (0x%x).\n",
        t->id, retval, retval);

#ifdef _WIN32
    return static_cast<DWORD>(retval);
#else /* _WIN32 */
    return reinterpret_cast<void *>(retval);
#endif /* _WIN32 */
}

/*
 * vislib::sys::Thread::Thread
 */
vislib::sys::Thread::Thread(const Thread& rhs) {
    throw UnsupportedOperationException("vislib::sys::Thread::Thread",
        __FILE__, __LINE__);
}

/*
 * vislib::sys::Thread::operator =
 */
vislib::sys::Thread& vislib::sys::Thread::operator =(const Thread& rhs) {
    if (this != &rhs) {
        throw IllegalParamException("rhs_", __FILE__, __LINE__);
    }

    return *this;
}
<|endoftext|>


<commit_before>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2014, Esteban Tovagliari. 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 Image Engine Design nor the names of any
//       other contributors to this software 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.
//
//////////////////////////////////////////////////////////////////////////

#include "boost/lexical_cast.hpp"

#include "renderer/api/color.h"

#include "IECore/MessageHandler.h"
#include "IECore/SimpleTypedData.h"

#include "IECoreAppleseed/private/AppleseedUtil.h"

using namespace IECore;
using namespace std;

namespace asf = foundation;
namespace asr = renderer;

string IECoreAppleseed::dataToString( ConstDataPtr value )
{
	stringstream ss;

	switch( value->typeId() )
	{
		case IntDataTypeId :
			{
				int x = static_cast<const IntData*>( value.get() )->readable();
				ss << x;
			}
			break;

		case FloatDataTypeId :
			{
				float x = static_cast<const FloatData*>( value.get() )->readable();
				ss << x;
			}
			break;

		case StringDataTypeId :
			{
				const string &x = static_cast<const StringData*>( value.get() )->readable();
				ss << x;
			}
			break;

		case V2iDataTypeId :
			{
				const Imath::V2i &x = static_cast<const V2iData*>( value.get() )->readable();
				ss << x.x << ", " << x.y;
			}
			break;

		case Color3fDataTypeId :
			{
				const Imath::Color3f &x = static_cast<const Color3fData*>( value.get() )->readable();
				ss << x.x << ", " << x.y << ", " << x.z;
			}
			break;
		case BoolDataTypeId :
			{
				bool x = static_cast<const BoolData*>( value.get() )->readable();
				ss << x;
			}
			break;

		default:
			break;
	}

	return ss.str();
}

void IECoreAppleseed::setParam( const string &name, const Data *value, asr::ParamArray &params )
{
	switch( value->typeId() )
	{
		case IntDataTypeId :
			{
				int x = static_cast<const IntData*>( value )->readable();
				params.insert( name, x );
			}
			break;

		case FloatDataTypeId :
			{
				float x = static_cast<const FloatData*>( value )->readable();
				params.insert( name, x );
			}
			break;

		case StringDataTypeId :
			{
				const string &x = static_cast<const StringData*>( value )->readable();
				params.insert( name, x.c_str() );
			}
			break;

		case BoolDataTypeId :
			{
				bool x = static_cast<const BoolData*>( value )->readable();
				params.insert( name, x );
			}
			break;

		default:
			// TODO: some kind of warning would be nice here...
			break;
	}
}

asr::ParamArray IECoreAppleseed::convertParams( const CompoundDataMap &parameters )
{
	asr::ParamArray result;

	for( CompoundDataMap::const_iterator it=parameters.begin(); it!=parameters.end(); ++it )
		setParam( it->first.value(), it->second.get(), result );

	return result;
}

string IECoreAppleseed::createColorEntity( asr::ColorContainer &colorContainer, const Imath::C3f &color, const string &name )
{
	// for monochrome colors, we don't need to create a color entity at all.
	if( color.x == color.y && color.x == color.z )
	{
		return boost::lexical_cast<string>( color.x );
	}

	asr::ColorValueArray values( 3, &color.x );
	asr::ParamArray params;
	params.insert( "color_space", "linear_rgb" );

	asf::auto_release_ptr<asr::ColorEntity> c = asr::ColorEntityFactory::create( name.c_str(), params, values );
	return insertEntityWithUniqueName( colorContainer, c, name.c_str() );
}

namespace
{

string doCreateTextureEntity( asr::TextureContainer &textureContainer, asr::TextureInstanceContainer &textureInstanceContainer, const asf::SearchPaths &searchPaths, const string &textureName, const string &fileName, const asr::ParamArray &txInstanceParams )
{
	asr::ParamArray params;
	params.insert( "filename", fileName.c_str() );
	params.insert( "color_space", "linear_rgb" );

	asf::auto_release_ptr<asr::Texture> texture( asr::DiskTexture2dFactory().create( textureName.c_str(), params, searchPaths ) );
	string txName = IECoreAppleseed::insertEntityWithUniqueName( textureContainer, texture, textureName );

	string textureInstanceName = txName + "_instance";
	asf::auto_release_ptr<asr::TextureInstance> textureInstance( asr::TextureInstanceFactory().create( textureInstanceName.c_str(), txInstanceParams, txName.c_str() ) );
	return IECoreAppleseed::insertEntityWithUniqueName( textureInstanceContainer, textureInstance, textureInstanceName.c_str() );
}

}

string IECoreAppleseed::createTextureEntity( asr::TextureContainer &textureContainer, asr::TextureInstanceContainer &textureInstanceContainer, const asf::SearchPaths &searchPaths, const string &textureName, const string &fileName )
{
	return doCreateTextureEntity( textureContainer, textureInstanceContainer, searchPaths, textureName, fileName, asr::ParamArray() );
}

string IECoreAppleseed::createAlphaMapTextureEntity( asr::TextureContainer &textureContainer, asr::TextureInstanceContainer &textureInstanceContainer, const asf::SearchPaths &searchPaths, const string &textureName, const string &fileName )
{
	asr::ParamArray params;
	params.insert( "alpha_mode", "detect" );
	return doCreateTextureEntity( textureContainer, textureInstanceContainer, searchPaths, textureName, fileName, params );
}
<commit_msg>Removed namespace qualifiers. Added some warnings.<commit_after>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2014, Esteban Tovagliari. 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 Image Engine Design nor the names of any
//       other contributors to this software 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.
//
//////////////////////////////////////////////////////////////////////////

#include "boost/lexical_cast.hpp"

#include "renderer/api/color.h"

#include "IECore/MessageHandler.h"
#include "IECore/SimpleTypedData.h"

#include "IECoreAppleseed/private/AppleseedUtil.h"

using namespace IECore;
using namespace Imath;
using namespace boost;
using namespace std;

namespace asf = foundation;
namespace asr = renderer;

string IECoreAppleseed::dataToString( ConstDataPtr value )
{
	stringstream ss;

	switch( value->typeId() )
	{
		case IntDataTypeId :
			{
				int x = static_cast<const IntData*>( value.get() )->readable();
				ss << x;
			}
			break;

		case FloatDataTypeId :
			{
				float x = static_cast<const FloatData*>( value.get() )->readable();
				ss << x;
			}
			break;

		case StringDataTypeId :
			{
				const string &x = static_cast<const StringData*>( value.get() )->readable();
				ss << x;
			}
			break;

		case V2iDataTypeId :
			{
				const V2i &x = static_cast<const V2iData*>( value.get() )->readable();
				ss << x.x << ", " << x.y;
			}
			break;

		case Color3fDataTypeId :
			{
				const Color3f &x = static_cast<const Color3fData*>( value.get() )->readable();
				ss << x.x << ", " << x.y << ", " << x.z;
			}
			break;
		case BoolDataTypeId :
			{
				bool x = static_cast<const BoolData*>( value.get() )->readable();
				ss << x;
			}
			break;

		default:
			msg( MessageHandler::Warning, "IECoreAppleseed::dataToString", format( "Unknown data typeid \"%s\"." ) % value->typeName() );
			break;
	}

	return ss.str();
}

void IECoreAppleseed::setParam( const string &name, const Data *value, asr::ParamArray &params )
{
	switch( value->typeId() )
	{
		case IntDataTypeId :
			{
				int x = static_cast<const IntData*>( value )->readable();
				params.insert( name, x );
			}
			break;

		case FloatDataTypeId :
			{
				float x = static_cast<const FloatData*>( value )->readable();
				params.insert( name, x );
			}
			break;

		case StringDataTypeId :
			{
				const string &x = static_cast<const StringData*>( value )->readable();
				params.insert( name, x.c_str() );
			}
			break;

		case BoolDataTypeId :
			{
				bool x = static_cast<const BoolData*>( value )->readable();
				params.insert( name, x );
			}
			break;

		default:
			msg( MessageHandler::Warning, "IECoreAppleseed::setParam", format( "Unknown data typeid \"%s\"." ) % value->typeName() );
			break;
	}
}

asr::ParamArray IECoreAppleseed::convertParams( const CompoundDataMap &parameters )
{
	asr::ParamArray result;

	for( CompoundDataMap::const_iterator it=parameters.begin(); it!=parameters.end(); ++it )
		setParam( it->first.value(), it->second.get(), result );

	return result;
}

string IECoreAppleseed::createColorEntity( asr::ColorContainer &colorContainer, const C3f &color, const string &name )
{
	// for monochrome colors, we don't need to create a color entity at all.
	if( color.x == color.y && color.x == color.z )
	{
		return lexical_cast<string>( color.x );
	}

	asr::ColorValueArray values( 3, &color.x );
	asr::ParamArray params;
	params.insert( "color_space", "linear_rgb" );

	asf::auto_release_ptr<asr::ColorEntity> c = asr::ColorEntityFactory::create( name.c_str(), params, values );
	return insertEntityWithUniqueName( colorContainer, c, name.c_str() );
}

namespace
{

string doCreateTextureEntity( asr::TextureContainer &textureContainer, asr::TextureInstanceContainer &textureInstanceContainer, const asf::SearchPaths &searchPaths, const string &textureName, const string &fileName, const asr::ParamArray &txInstanceParams )
{
	asr::ParamArray params;
	params.insert( "filename", fileName.c_str() );
	params.insert( "color_space", "linear_rgb" );

	asf::auto_release_ptr<asr::Texture> texture( asr::DiskTexture2dFactory().create( textureName.c_str(), params, searchPaths ) );
	string txName = IECoreAppleseed::insertEntityWithUniqueName( textureContainer, texture, textureName );

	string textureInstanceName = txName + "_instance";
	asf::auto_release_ptr<asr::TextureInstance> textureInstance( asr::TextureInstanceFactory().create( textureInstanceName.c_str(), txInstanceParams, txName.c_str() ) );
	return IECoreAppleseed::insertEntityWithUniqueName( textureInstanceContainer, textureInstance, textureInstanceName.c_str() );
}

}

string IECoreAppleseed::createTextureEntity( asr::TextureContainer &textureContainer, asr::TextureInstanceContainer &textureInstanceContainer, const asf::SearchPaths &searchPaths, const string &textureName, const string &fileName )
{
	return doCreateTextureEntity( textureContainer, textureInstanceContainer, searchPaths, textureName, fileName, asr::ParamArray() );
}

string IECoreAppleseed::createAlphaMapTextureEntity( asr::TextureContainer &textureContainer, asr::TextureInstanceContainer &textureInstanceContainer, const asf::SearchPaths &searchPaths, const string &textureName, const string &fileName )
{
	asr::ParamArray params;
	params.insert( "alpha_mode", "detect" );
	return doCreateTextureEntity( textureContainer, textureInstanceContainer, searchPaths, textureName, fileName, params );
}
<|endoftext|>


<commit_before>/*
 *
 * Copyright 2015, Google 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 Google Inc. 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.
 *
 */

#include <node.h>

#include "grpc/grpc.h"
#include "grpc/grpc_security.h"
#include "grpc/support/log.h"
#include "server_credentials.h"

namespace grpc {
namespace node {

using Nan::Callback;
using Nan::EscapableHandleScope;
using Nan::HandleScope;
using Nan::Maybe;
using Nan::MaybeLocal;
using Nan::ObjectWrap;
using Nan::Persistent;
using Nan::Utf8String;

using v8::Array;
using v8::Exception;
using v8::External;
using v8::Function;
using v8::FunctionTemplate;
using v8::Integer;
using v8::Local;
using v8::Object;
using v8::ObjectTemplate;
using v8::String;
using v8::Value;

Nan::Callback *ServerCredentials::constructor;
Persistent<FunctionTemplate> ServerCredentials::fun_tpl;

ServerCredentials::ServerCredentials(grpc_server_credentials *credentials)
    : wrapped_credentials(credentials) {}

ServerCredentials::~ServerCredentials() {
  grpc_server_credentials_release(wrapped_credentials);
}

void ServerCredentials::Init(Local<Object> exports) {
  Nan::HandleScope scope;
  Local<FunctionTemplate> tpl = Nan::New<FunctionTemplate>(New);
  tpl->SetClassName(Nan::New("ServerCredentials").ToLocalChecked());
  tpl->InstanceTemplate()->SetInternalFieldCount(1);
  Local<Function> ctr = tpl->GetFunction();
  Nan::Set(ctr, Nan::New("createSsl").ToLocalChecked(),
           Nan::GetFunction(
               Nan::New<FunctionTemplate>(CreateSsl)).ToLocalChecked());
  Nan::Set(ctr, Nan::New("createInsecure").ToLocalChecked(),
           Nan::GetFunction(
               Nan::New<FunctionTemplate>(CreateInsecure)).ToLocalChecked());
  fun_tpl.Reset(tpl);
  constructor = new Nan::Callback(ctr);
  Nan::Set(exports, Nan::New("ServerCredentials").ToLocalChecked(), ctr);
}

bool ServerCredentials::HasInstance(Local<Value> val) {
  Nan::HandleScope scope;
  return Nan::New(fun_tpl)->HasInstance(val);
}

Local<Value> ServerCredentials::WrapStruct(
    grpc_server_credentials *credentials) {
  Nan::EscapableHandleScope scope;
  const int argc = 1;
  Local<Value> argv[argc] = {
    Nan::New<External>(reinterpret_cast<void *>(credentials))};
  MaybeLocal<Object> maybe_instance = Nan::NewInstance(
      constructor->GetFunction(), argc, argv);
  if (maybe_instance.IsEmpty()) {
    return scope.Escape(Nan::Null());
  } else {
    return scope.Escape(maybe_instance.ToLocalChecked());
  }
}

grpc_server_credentials *ServerCredentials::GetWrappedServerCredentials() {
  return wrapped_credentials;
}

NAN_METHOD(ServerCredentials::New) {
  if (info.IsConstructCall()) {
    if (!info[0]->IsExternal()) {
      return Nan::ThrowTypeError(
          "ServerCredentials can only be created with the provided functions");
    }
    Local<External> ext = info[0].As<External>();
    grpc_server_credentials *creds_value =
        reinterpret_cast<grpc_server_credentials *>(ext->Value());
    ServerCredentials *credentials = new ServerCredentials(creds_value);
    credentials->Wrap(info.This());
    info.GetReturnValue().Set(info.This());
  } else {
    // This should never be called directly
    return Nan::ThrowTypeError(
        "ServerCredentials can only be created with the provided functions");
  }
}

NAN_METHOD(ServerCredentials::CreateSsl) {
  Nan::HandleScope scope;
  char *root_certs = NULL;
  if (::node::Buffer::HasInstance(info[0])) {
    root_certs = ::node::Buffer::Data(info[0]);
  } else if (!(info[0]->IsNull() || info[0]->IsUndefined())) {
    return Nan::ThrowTypeError(
        "createSSl's first argument must be a Buffer if provided");
  }
  if (!info[1]->IsArray()) {
    return Nan::ThrowTypeError(
        "createSsl's second argument must be a list of objects");
  }
  int force_client_auth = 0;
  if (info[2]->IsBoolean()) {
    force_client_auth = (int)Nan::To<bool>(info[2]).FromJust();
  } else if (!(info[2]->IsUndefined() || info[2]->IsNull())) {
    return Nan::ThrowTypeError(
        "createSsl's third argument must be a boolean if provided");
  }
  Local<Array> pair_list = Local<Array>::Cast(info[1]);
  uint32_t key_cert_pair_count = pair_list->Length();
  grpc_ssl_pem_key_cert_pair *key_cert_pairs = new grpc_ssl_pem_key_cert_pair[
      key_cert_pair_count];

  Local<String> key_key = Nan::New("private_key").ToLocalChecked();
  Local<String> cert_key = Nan::New("cert_chain").ToLocalChecked();

  for(uint32_t i = 0; i < key_cert_pair_count; i++) {
    Local<Value> pair_val = Nan::Get(pair_list, i).ToLocalChecked();
    if (!pair_val->IsObject()) {
      delete key_cert_pairs;
      return Nan::ThrowTypeError("Key/cert pairs must be objects");
    }
    Local<Object> pair_obj = Nan::To<Object>(pair_val).ToLocalChecked();
    Local<Value> maybe_key = Nan::Get(pair_obj, key_key).ToLocalChecked();
    Local<Value> maybe_cert = Nan::Get(pair_obj, cert_key).ToLocalChecked();
    if (!::node::Buffer::HasInstance(maybe_key)) {
      delete key_cert_pairs;
      return Nan::ThrowTypeError("private_key must be a Buffer");
    }
    if (!::node::Buffer::HasInstance(maybe_cert)) {
      delete key_cert_pairs;
      return Nan::ThrowTypeError("cert_chain must be a Buffer");
    }
    key_cert_pairs[i].private_key = ::node::Buffer::Data(maybe_key);
    key_cert_pairs[i].cert_chain = ::node::Buffer::Data(maybe_cert);
  }
  grpc_server_credentials *creds = grpc_ssl_server_credentials_create(
      root_certs, key_cert_pairs, key_cert_pair_count, force_client_auth, NULL);
  delete key_cert_pairs;
  if (creds == NULL) {
    info.GetReturnValue().SetNull();
  } else {
    info.GetReturnValue().Set(WrapStruct(creds));
  }
}

NAN_METHOD(ServerCredentials::CreateInsecure) {
  info.GetReturnValue().Set(WrapStruct(NULL));
}

}  // namespace node
}  // namespace grpc
<commit_msg>Add various options to verify ssl/tls client cert including letting the application handle the authentication.<commit_after>/*
 *
 * Copyright 2015, Google 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 Google Inc. 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.
 *
 */

#include <node.h>

#include "grpc/grpc.h"
#include "grpc/grpc_security.h"
#include "grpc/support/log.h"
#include "server_credentials.h"

namespace grpc {
namespace node {

using Nan::Callback;
using Nan::EscapableHandleScope;
using Nan::HandleScope;
using Nan::Maybe;
using Nan::MaybeLocal;
using Nan::ObjectWrap;
using Nan::Persistent;
using Nan::Utf8String;

using v8::Array;
using v8::Exception;
using v8::External;
using v8::Function;
using v8::FunctionTemplate;
using v8::Integer;
using v8::Local;
using v8::Object;
using v8::ObjectTemplate;
using v8::String;
using v8::Value;

Nan::Callback *ServerCredentials::constructor;
Persistent<FunctionTemplate> ServerCredentials::fun_tpl;

ServerCredentials::ServerCredentials(grpc_server_credentials *credentials)
    : wrapped_credentials(credentials) {}

ServerCredentials::~ServerCredentials() {
  grpc_server_credentials_release(wrapped_credentials);
}

void ServerCredentials::Init(Local<Object> exports) {
  Nan::HandleScope scope;
  Local<FunctionTemplate> tpl = Nan::New<FunctionTemplate>(New);
  tpl->SetClassName(Nan::New("ServerCredentials").ToLocalChecked());
  tpl->InstanceTemplate()->SetInternalFieldCount(1);
  Local<Function> ctr = tpl->GetFunction();
  Nan::Set(ctr, Nan::New("createSsl").ToLocalChecked(),
           Nan::GetFunction(
               Nan::New<FunctionTemplate>(CreateSsl)).ToLocalChecked());
  Nan::Set(ctr, Nan::New("createInsecure").ToLocalChecked(),
           Nan::GetFunction(
               Nan::New<FunctionTemplate>(CreateInsecure)).ToLocalChecked());
  fun_tpl.Reset(tpl);
  constructor = new Nan::Callback(ctr);
  Nan::Set(exports, Nan::New("ServerCredentials").ToLocalChecked(), ctr);
}

bool ServerCredentials::HasInstance(Local<Value> val) {
  Nan::HandleScope scope;
  return Nan::New(fun_tpl)->HasInstance(val);
}

Local<Value> ServerCredentials::WrapStruct(
    grpc_server_credentials *credentials) {
  Nan::EscapableHandleScope scope;
  const int argc = 1;
  Local<Value> argv[argc] = {
    Nan::New<External>(reinterpret_cast<void *>(credentials))};
  MaybeLocal<Object> maybe_instance = Nan::NewInstance(
      constructor->GetFunction(), argc, argv);
  if (maybe_instance.IsEmpty()) {
    return scope.Escape(Nan::Null());
  } else {
    return scope.Escape(maybe_instance.ToLocalChecked());
  }
}

grpc_server_credentials *ServerCredentials::GetWrappedServerCredentials() {
  return wrapped_credentials;
}

NAN_METHOD(ServerCredentials::New) {
  if (info.IsConstructCall()) {
    if (!info[0]->IsExternal()) {
      return Nan::ThrowTypeError(
          "ServerCredentials can only be created with the provided functions");
    }
    Local<External> ext = info[0].As<External>();
    grpc_server_credentials *creds_value =
        reinterpret_cast<grpc_server_credentials *>(ext->Value());
    ServerCredentials *credentials = new ServerCredentials(creds_value);
    credentials->Wrap(info.This());
    info.GetReturnValue().Set(info.This());
  } else {
    // This should never be called directly
    return Nan::ThrowTypeError(
        "ServerCredentials can only be created with the provided functions");
  }
}

NAN_METHOD(ServerCredentials::CreateSsl) {
  Nan::HandleScope scope;
  char *root_certs = NULL;
  if (::node::Buffer::HasInstance(info[0])) {
    root_certs = ::node::Buffer::Data(info[0]);
  } else if (!(info[0]->IsNull() || info[0]->IsUndefined())) {
    return Nan::ThrowTypeError(
        "createSSl's first argument must be a Buffer if provided");
  }
  if (!info[1]->IsArray()) {
    return Nan::ThrowTypeError(
        "createSsl's second argument must be a list of objects");
  }

  grpc_ssl_client_certificate_request_type client_certificate_request;
  if (info[2]->IsBoolean()) {
    client_certificate_request =
        Nan::To<bool>(info[2]).FromJust()
            ? GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY
            : GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE;
  } else if (!(info[2]->IsUndefined() || info[2]->IsNull())) {
    return Nan::ThrowTypeError(
        "createSsl's third argument must be a boolean if provided");
  }
  Local<Array> pair_list = Local<Array>::Cast(info[1]);
  uint32_t key_cert_pair_count = pair_list->Length();
  grpc_ssl_pem_key_cert_pair *key_cert_pairs = new grpc_ssl_pem_key_cert_pair[
      key_cert_pair_count];

  Local<String> key_key = Nan::New("private_key").ToLocalChecked();
  Local<String> cert_key = Nan::New("cert_chain").ToLocalChecked();

  for(uint32_t i = 0; i < key_cert_pair_count; i++) {
    Local<Value> pair_val = Nan::Get(pair_list, i).ToLocalChecked();
    if (!pair_val->IsObject()) {
      delete key_cert_pairs;
      return Nan::ThrowTypeError("Key/cert pairs must be objects");
    }
    Local<Object> pair_obj = Nan::To<Object>(pair_val).ToLocalChecked();
    Local<Value> maybe_key = Nan::Get(pair_obj, key_key).ToLocalChecked();
    Local<Value> maybe_cert = Nan::Get(pair_obj, cert_key).ToLocalChecked();
    if (!::node::Buffer::HasInstance(maybe_key)) {
      delete key_cert_pairs;
      return Nan::ThrowTypeError("private_key must be a Buffer");
    }
    if (!::node::Buffer::HasInstance(maybe_cert)) {
      delete key_cert_pairs;
      return Nan::ThrowTypeError("cert_chain must be a Buffer");
    }
    key_cert_pairs[i].private_key = ::node::Buffer::Data(maybe_key);
    key_cert_pairs[i].cert_chain = ::node::Buffer::Data(maybe_cert);
  }
  grpc_server_credentials *creds = grpc_ssl_server_credentials_create_ex(
      root_certs, key_cert_pairs, key_cert_pair_count,
      client_certificate_request, NULL);
  delete key_cert_pairs;
  if (creds == NULL) {
    info.GetReturnValue().SetNull();
  } else {
    info.GetReturnValue().Set(WrapStruct(creds));
  }
}

NAN_METHOD(ServerCredentials::CreateInsecure) {
  info.GetReturnValue().Set(WrapStruct(NULL));
}

}  // namespace node
}  // namespace grpc
<|endoftext|>


<commit_before>#pragma once

#include "../traits.hpp"
#include "fft2d.pb.h"
#include <thrust/device_vector.h>

namespace cujak {
namespace fft2d {

inline int calc_stride(int Ny) { return Ny / 2 + 1; }

template <typename Container> class wrapper_base {
protected:
  const int Nx, Ny, stride, N;
  Container &u;
  wrapper_base(int Nx_, int Ny_, int stride_, int N_, Container &u_)
      : Nx(Nx_), Ny(Ny_), stride(stride_), N(N_), u(u_) {}

public:
  typedef typename Container::value_type value_type;

  pb::Property property;

  value_type *get() const { return u.data().get(); }
  Container &data() const { return u; }

  value_type operator()(int i, int j) const {
    if (i >= 0) {
      return u[stride * i + j];
    } else {
      return u[stride * (Nx + i) + j];
    }
  }
  void set(int i, int j, value_type v) {
    if (i >= 0) {
      u[stride * i + j] = v;
    } else {
      u[stride * (Nx + i) + j] = v;
    }
  }

  int size_x() const { return Nx; }
  int size_y() const { return Ny; }
  int size() const { return N; }
  int get_stride() const { return stride; }
};

template <typename Float>
class Field_wrapper : public wrapper_base<rdVector<Float> > {
public:
  typedef rdVector<Float> Container;
  Field_wrapper(int Nx, int Ny, Container &u)
      : wrapper_base<Container>(Nx, Ny, Ny, Nx * Ny, u) {}
  virtual ~Field_wrapper() = default;
};

template <typename Float>
class Coefficient_wrapper : public wrapper_base<cdVector<Float> > {

public:
  typedef cdVector<Float> Container;
  Coefficient_wrapper(int Nx, int Ny, Container &u)
      : wrapper_base<Container>(Nx, Ny, calc_stride(Ny), Nx * calc_stride(Ny),
                                u) {}
  virtual ~Coefficient_wrapper() = default;
};

template <typename Float> class Field : public Field_wrapper<Float> {
  typename Field_wrapper<Float>::Container data_;

public:
  Field(int Nx, int Ny) : data_(Nx * Ny), Field_wrapper<Float>(Nx, Ny, data_) {}
};

template <typename Float>
class Coefficient : public Coefficient_wrapper<Float> {
  typename Coefficient<Float>::Container data_;

public:
  Coefficient(int Nx, int Ny)
      : data_(Nx * calc_stride(Ny)), Coefficient_wrapper<Float>(Nx, Ny, data_) {
  }
};

} // namespace fft2d
} // namespace Kolmogorov2D
<commit_msg>Add begin/end<commit_after>#pragma once

#include "../traits.hpp"
#include "fft2d.pb.h"
#include <thrust/device_vector.h>

namespace cujak {
namespace fft2d {

inline int calc_stride(int Ny) { return Ny / 2 + 1; }

template <typename Container> class wrapper_base {
protected:
  const int Nx, Ny, stride, N;
  Container &u;
  wrapper_base(int Nx_, int Ny_, int stride_, int N_, Container &u_)
      : Nx(Nx_), Ny(Ny_), stride(stride_), N(N_), u(u_) {}

public:
  typedef typename Container::value_type value_type;
  typedef decltype(u.begin()) iterator;

  pb::Property property;

  value_type *get() const { return u.data().get(); }
  Container &data() const { return u; }
  iterator begin() const { return u.begin(); }
  iterator end() const { return u.end(); }

  value_type operator()(int i, int j) const {
    if (i >= 0) {
      return u[stride * i + j];
    } else {
      return u[stride * (Nx + i) + j];
    }
  }
  void set(int i, int j, value_type v) {
    if (i >= 0) {
      u[stride * i + j] = v;
    } else {
      u[stride * (Nx + i) + j] = v;
    }
  }

  int size_x() const { return Nx; }
  int size_y() const { return Ny; }
  int size() const { return N; }
  int get_stride() const { return stride; }
};

template <typename Float>
class Field_wrapper : public wrapper_base<rdVector<Float> > {
public:
  typedef rdVector<Float> Container;
  Field_wrapper(int Nx, int Ny, Container &u)
      : wrapper_base<Container>(Nx, Ny, Ny, Nx * Ny, u) {}
  virtual ~Field_wrapper() = default;
};

template <typename Float>
class Coefficient_wrapper : public wrapper_base<cdVector<Float> > {

public:
  typedef cdVector<Float> Container;
  Coefficient_wrapper(int Nx, int Ny, Container &u)
      : wrapper_base<Container>(Nx, Ny, calc_stride(Ny), Nx * calc_stride(Ny),
                                u) {}
  virtual ~Coefficient_wrapper() = default;
};

template <typename Float> class Field : public Field_wrapper<Float> {
  typename Field_wrapper<Float>::Container data_;

public:
  Field(int Nx, int Ny) : data_(Nx * Ny), Field_wrapper<Float>(Nx, Ny, data_) {}
};

template <typename Float>
class Coefficient : public Coefficient_wrapper<Float> {
  typename Coefficient<Float>::Container data_;

public:
  Coefficient(int Nx, int Ny)
      : data_(Nx * calc_stride(Ny)), Coefficient_wrapper<Float>(Nx, Ny, data_) {
  }
};

} // namespace fft2d
} // namespace Kolmogorov2D
<|endoftext|>


<commit_before>// The MIT License (MIT)

// Copyright (c) 2015 nabijaczleweli

// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#ifndef HASHABLE_HPP
#define HASHABLE_HPP

#include <functional>

namespace cpponfiguration {
	// T must publicly interhit hashable<T>, as in `class foo : public hashable<foo> {};`
	template <class T>
	class hashable {
		friend std::hash<hashable<T>>;

	protected:
		virtual size_t hash_code() const = 0;

		inline virtual ~hashable() noexcept = default;
	};
}

namespace cpponfig = cpponfiguration;

namespace std {
	template <class T>
	struct hash<cpponfig::hashable<T>> {
		inline size_t operator()(const cpponfig::hashable<T> & tohash) const {
			return tohash.hash_code();
		}
	};

	template <class T>
	struct hash : std::hash<cpponfig::hashable<T>> {};
}

#endif  // HASHABLE_HPP
<commit_msg>Revert "Explicitly specify the namespace"<commit_after>// The MIT License (MIT)

// Copyright (c) 2015 nabijaczleweli

// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#ifndef HASHABLE_HPP
#define HASHABLE_HPP

#include <functional>

namespace cpponfiguration {
	// T must publicly interhit hashable<T>, as in `class foo : public hashable<foo> {};`
	template <class T>
	class hashable {
		friend std::hash<hashable<T>>;

	protected:
		virtual size_t hash_code() const = 0;

		inline virtual ~hashable() noexcept = default;
	};
}

namespace cpponfig = cpponfiguration;

namespace std {
	template <class T>
	struct hash<cpponfig::hashable<T>> {
		inline size_t operator()(const cpponfig::hashable<T> & tohash) const {
			return tohash.hash_code();
		}
	};

	template <class T>
	struct hash : hash<cpponfig::hashable<T>> {};
}

#endif  // HASHABLE_HPP
<|endoftext|>