<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkGeometricErrorMetric.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkGeometricErrorMetric.h"

#include "vtkObjectFactory.h"
#include "vtkGenericAttribute.h"
#include "vtkGenericAttributeCollection.h"
#include "vtkGenericAdaptorCell.h"
#include "vtkGenericDataSet.h"
#include "vtkMath.h"
#include <assert.h>

vtkCxxRevisionMacro(vtkGeometricErrorMetric,"1.6");
vtkStandardNewMacro(vtkGeometricErrorMetric);

//-----------------------------------------------------------------------------
vtkGeometricErrorMetric::vtkGeometricErrorMetric()
{
  this->AbsoluteGeometricTolerance = 1.0; // arbitrary positive value
  this->Relative=0; // GetError() will return the square absolute error.
  this->SmallestSize=1;
}

//-----------------------------------------------------------------------------
vtkGeometricErrorMetric::~vtkGeometricErrorMetric()
{
}

//-----------------------------------------------------------------------------
// Description :
// Set the geometric accuracy with an absolute value.
// Subdivision will be required if the square distance is greater than
// value. For instance 0.01 will give better result than 0.1.
// \pre positive_value: value>0
void vtkGeometricErrorMetric::SetAbsoluteGeometricTolerance(double value)
{
  assert("pre: positive_value" && value>0);
  this->Relative=0;
  if(this->AbsoluteGeometricTolerance!=value)
    {
    this->AbsoluteGeometricTolerance=value;
    this->Modified();
    }
}

//-----------------------------------------------------------------------------
// Description :
// Set the geometric accuracy with a value relative to the bounding box of
// the dataset. Internally compute the absolute tolerance.
// For instance 0.01 will give better result than 0.1.
// \pre valid_range_value: value>0 && value<1
// \pre ds_exists: ds!=0
void vtkGeometricErrorMetric::SetRelativeGeometricTolerance(double value,
                                                            vtkGenericDataSet *ds)
{
  assert("pre: valid_range_value" && value>0 && value<1);
  assert("pre: ds_exists" && ds!=0);

  double bounds[6];
  ds->GetBounds(bounds);
  double smallest;
  double length;
  smallest = bounds[1] - bounds[0];
  length   = bounds[3] - bounds[2];
  if(length < smallest || smallest == 0.0)
    {
    smallest = length;
    }
  length = bounds[5] - bounds[4];
  if(length < smallest || smallest == 0.0)
    {
    smallest = length;
    }
  length = ds->GetLength();
  if(length < smallest || smallest == 0.0)
    {
    smallest = length;
    }
  if(smallest == 0)
    {
    smallest = 1;
    }
  double tmp = value*smallest;
  this->SmallestSize=smallest;
  cout<<"this->SmallestSize="<<this->SmallestSize<<endl;
  this->Relative=1;
  tmp=tmp*tmp;

  if(this->AbsoluteGeometricTolerance!=tmp)
    {
    this->AbsoluteGeometricTolerance = tmp;
    this->Modified();
    }
}

#define VTK_DISTANCE_LINE_POINT

//-----------------------------------------------------------------------------
int vtkGeometricErrorMetric::RequiresEdgeSubdivision(double *leftPoint,
                                                     double *midPoint,
                                                     double *rightPoint,
#ifdef VTK_DISTANCE_LINE_POINT
                                                     double vtkNotUsed(alpha)
#else
                                                     double alpha
#endif
  )
{
  assert("pre: leftPoint_exists" && leftPoint!=0);
  assert("pre: midPoint_exists" && midPoint!=0);
  assert("pre: rightPoint_exists" && rightPoint!=0);
//  assert("pre: clamped_alpha" && alpha>0 && alpha<1); // or else true
  if( this->GenericCell->IsGeometryLinear() )
    {
    //don't need to do anything:
    return 0;
    }
  // distance between the line (leftPoint,rightPoint) and the point midPoint.
#ifdef VTK_DISTANCE_LINE_POINT
  return this->Distance2LinePoint(leftPoint,rightPoint,midPoint)>this->AbsoluteGeometricTolerance;
#else
  // Interpolated point
  double interpolatedPoint[3];
  int i=0;
  while(i<3)
    {
    interpolatedPoint[i]=leftPoint[i] + alpha*(rightPoint[i] - leftPoint[i]);
    ++i;
    }
  return vtkMath::Distance2BetweenPoints(midPoint,interpolatedPoint)>this->AbsoluteGeometricTolerance;
#endif
}

//-----------------------------------------------------------------------------
// Description:
// Return the error at the mid-point. The type of error depends on the state
// of the concrete error metric. For instance, it can return an absolute
// or relative error metric.
// See RequiresEdgeSubdivision() for a description of the arguments.
// \post positive_result: result>=0
double vtkGeometricErrorMetric::GetError(double *leftPoint,
                                         double *midPoint,
                                         double *rightPoint,
#ifdef VTK_DISTANCE_LINE_POINT
                                         double vtkNotUsed(alpha)
#else
                                         double alpha
#endif
  )
{
  assert("pre: leftPoint_exists" && leftPoint!=0);
  assert("pre: midPoint_exists" && midPoint!=0);
  assert("pre: rightPoint_exists" && rightPoint!=0);
//  assert("pre: clamped_alpha" && alpha>0 && alpha<1); // or else true
  if( this->GenericCell->IsGeometryLinear() )
    {
    //don't need to do anything:
    return 0;
    }
  // distance between the line (leftPoint,rightPoint) and the point midPoint.
#ifdef VTK_DISTANCE_LINE_POINT
  double squareAbsoluteError=this->Distance2LinePoint(leftPoint,rightPoint,midPoint);
#else
   // Interpolated point
  double interpolatedPoint[3];
  int i=0;
  while(i<3)
    {
    interpolatedPoint[i]=leftPoint[i] + alpha*(rightPoint[i] - leftPoint[i]);
    ++i;
    }
  double squareAbsoluteError=vtkMath::Distance2BetweenPoints(midPoint,interpolatedPoint);
#endif
  if(this->Relative)
    {
    return sqrt(squareAbsoluteError)*this->SmallestSize;
    }
  else
    {
    return squareAbsoluteError;
    }
}

//-----------------------------------------------------------------------------
// Description:
// Return the type of output of GetError()
int vtkGeometricErrorMetric::GetRelative()
{
  return this->Relative;
}

//-----------------------------------------------------------------------------
// Description:
// Square distance between a straight line (defined by points x and y)
// and a point z. Property: if x and y are equal, the line is a point and
// the result is the square distance between points x and z.
double vtkGeometricErrorMetric::Distance2LinePoint(double x[3],
                                                   double y[3],
                                                   double z[3])
{
  double u[3];
  double v[3];
  double w[3];

  u[0] = y[0] - x[0];
  u[1] = y[1] - x[1];
  u[2] = y[2] - x[2];

  vtkMath::Normalize(u);

  v[0] = z[0] - x[0];
  v[1] = z[1] - x[1];
  v[2] = z[2] - x[2];

  double dot = vtkMath::Dot(u,v);

  w[0] = v[0] - dot*u[0];
  w[1] = v[1] - dot*u[1];
  w[2] = v[2] - dot*u[2];

  return vtkMath::Dot(w,w);
}

//-----------------------------------------------------------------------------
void vtkGeometricErrorMetric::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);

  os << indent << "AbsoluteGeometricTolerance: "  << this->AbsoluteGeometricTolerance << endl;
}
<commit_msg>BUG:Fixed an elementary school level mistake<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkGeometricErrorMetric.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkGeometricErrorMetric.h"

#include "vtkObjectFactory.h"
#include "vtkGenericAttribute.h"
#include "vtkGenericAttributeCollection.h"
#include "vtkGenericAdaptorCell.h"
#include "vtkGenericDataSet.h"
#include "vtkMath.h"
#include <assert.h>

vtkCxxRevisionMacro(vtkGeometricErrorMetric,"1.7");
vtkStandardNewMacro(vtkGeometricErrorMetric);

//-----------------------------------------------------------------------------
vtkGeometricErrorMetric::vtkGeometricErrorMetric()
{
  this->AbsoluteGeometricTolerance = 1.0; // arbitrary positive value
  this->Relative=0; // GetError() will return the square absolute error.
  this->SmallestSize=1;
}

//-----------------------------------------------------------------------------
vtkGeometricErrorMetric::~vtkGeometricErrorMetric()
{
}

//-----------------------------------------------------------------------------
// Description :
// Set the geometric accuracy with an absolute value.
// Subdivision will be required if the square distance is greater than
// value. For instance 0.01 will give better result than 0.1.
// \pre positive_value: value>0
void vtkGeometricErrorMetric::SetAbsoluteGeometricTolerance(double value)
{
  assert("pre: positive_value" && value>0);
  this->Relative=0;
  if(this->AbsoluteGeometricTolerance!=value)
    {
    this->AbsoluteGeometricTolerance=value;
    this->Modified();
    }
}

//-----------------------------------------------------------------------------
// Description :
// Set the geometric accuracy with a value relative to the bounding box of
// the dataset. Internally compute the absolute tolerance.
// For instance 0.01 will give better result than 0.1.
// \pre valid_range_value: value>0 && value<1
// \pre ds_exists: ds!=0
void vtkGeometricErrorMetric::SetRelativeGeometricTolerance(double value,
                                                            vtkGenericDataSet *ds)
{
  assert("pre: valid_range_value" && value>0 && value<1);
  assert("pre: ds_exists" && ds!=0);

  double bounds[6];
  ds->GetBounds(bounds);
  double smallest;
  double length;
  smallest = bounds[1] - bounds[0];
  length   = bounds[3] - bounds[2];
  if(length < smallest || smallest == 0.0)
    {
    smallest = length;
    }
  length = bounds[5] - bounds[4];
  if(length < smallest || smallest == 0.0)
    {
    smallest = length;
    }
  length = ds->GetLength();
  if(length < smallest || smallest == 0.0)
    {
    smallest = length;
    }
  if(smallest == 0)
    {
    smallest = 1;
    }
  double tmp = value*smallest;
  this->SmallestSize=smallest;
  cout<<"this->SmallestSize="<<this->SmallestSize<<endl;
  this->Relative=1;
  tmp=tmp*tmp;

  if(this->AbsoluteGeometricTolerance!=tmp)
    {
    this->AbsoluteGeometricTolerance = tmp;
    this->Modified();
    }
}

#define VTK_DISTANCE_LINE_POINT

//-----------------------------------------------------------------------------
int vtkGeometricErrorMetric::RequiresEdgeSubdivision(double *leftPoint,
                                                     double *midPoint,
                                                     double *rightPoint,
#ifdef VTK_DISTANCE_LINE_POINT
                                                     double vtkNotUsed(alpha)
#else
                                                     double alpha
#endif
  )
{
  assert("pre: leftPoint_exists" && leftPoint!=0);
  assert("pre: midPoint_exists" && midPoint!=0);
  assert("pre: rightPoint_exists" && rightPoint!=0);
//  assert("pre: clamped_alpha" && alpha>0 && alpha<1); // or else true
  if( this->GenericCell->IsGeometryLinear() )
    {
    //don't need to do anything:
    return 0;
    }
  // distance between the line (leftPoint,rightPoint) and the point midPoint.
#ifdef VTK_DISTANCE_LINE_POINT
  return this->Distance2LinePoint(leftPoint,rightPoint,midPoint)>this->AbsoluteGeometricTolerance;
#else
  // Interpolated point
  double interpolatedPoint[3];
  int i=0;
  while(i<3)
    {
    interpolatedPoint[i]=leftPoint[i] + alpha*(rightPoint[i] - leftPoint[i]);
    ++i;
    }
  return vtkMath::Distance2BetweenPoints(midPoint,interpolatedPoint)>this->AbsoluteGeometricTolerance;
#endif
}

//-----------------------------------------------------------------------------
// Description:
// Return the error at the mid-point. The type of error depends on the state
// of the concrete error metric. For instance, it can return an absolute
// or relative error metric.
// See RequiresEdgeSubdivision() for a description of the arguments.
// \post positive_result: result>=0
double vtkGeometricErrorMetric::GetError(double *leftPoint,
                                         double *midPoint,
                                         double *rightPoint,
#ifdef VTK_DISTANCE_LINE_POINT
                                         double vtkNotUsed(alpha)
#else
                                         double alpha
#endif
  )
{
  assert("pre: leftPoint_exists" && leftPoint!=0);
  assert("pre: midPoint_exists" && midPoint!=0);
  assert("pre: rightPoint_exists" && rightPoint!=0);
//  assert("pre: clamped_alpha" && alpha>0 && alpha<1); // or else true
  if( this->GenericCell->IsGeometryLinear() )
    {
    //don't need to do anything:
    return 0;
    }
  // distance between the line (leftPoint,rightPoint) and the point midPoint.
#ifdef VTK_DISTANCE_LINE_POINT
  double squareAbsoluteError=this->Distance2LinePoint(leftPoint,rightPoint,midPoint);
#else
   // Interpolated point
  double interpolatedPoint[3];
  int i=0;
  while(i<3)
    {
    interpolatedPoint[i]=leftPoint[i] + alpha*(rightPoint[i] - leftPoint[i]);
    ++i;
    }
  double squareAbsoluteError=vtkMath::Distance2BetweenPoints(midPoint,interpolatedPoint);
#endif
  if(this->Relative)
    {
    return sqrt(squareAbsoluteError)/this->SmallestSize;
    }
  else
    {
    return squareAbsoluteError;
    }
}

//-----------------------------------------------------------------------------
// Description:
// Return the type of output of GetError()
int vtkGeometricErrorMetric::GetRelative()
{
  return this->Relative;
}

//-----------------------------------------------------------------------------
// Description:
// Square distance between a straight line (defined by points x and y)
// and a point z. Property: if x and y are equal, the line is a point and
// the result is the square distance between points x and z.
double vtkGeometricErrorMetric::Distance2LinePoint(double x[3],
                                                   double y[3],
                                                   double z[3])
{
  double u[3];
  double v[3];
  double w[3];

  u[0] = y[0] - x[0];
  u[1] = y[1] - x[1];
  u[2] = y[2] - x[2];

  vtkMath::Normalize(u);

  v[0] = z[0] - x[0];
  v[1] = z[1] - x[1];
  v[2] = z[2] - x[2];

  double dot = vtkMath::Dot(u,v);

  w[0] = v[0] - dot*u[0];
  w[1] = v[1] - dot*u[1];
  w[2] = v[2] - dot*u[2];

  return vtkMath::Dot(w,w);
}

//-----------------------------------------------------------------------------
void vtkGeometricErrorMetric::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);

  os << indent << "AbsoluteGeometricTolerance: "  << this->AbsoluteGeometricTolerance << endl;
}
<|endoftext|>


<commit_before>#include "xchainer/array_body.h"

#include <algorithm>
#include <cassert>
#include <cstdint>
#include <memory>
#include <utility>

#include "xchainer/array.h"
#include "xchainer/array_body_leak_detection.h"
#include "xchainer/array_node.h"
#include "xchainer/backward.h"
#include "xchainer/dtype.h"
#include "xchainer/error.h"
#include "xchainer/graph.h"

namespace xchainer {
namespace internal {

std::shared_ptr<ArrayBody> CreateArrayBody(
        const Shape& shape, const Strides& strides, Dtype dtype, Device& device, std::shared_ptr<void> data, int64_t offset) {
    // Trick to use make_shared with private ctor
    struct ArrayBodyWithPublicCtor : ArrayBody {
        ArrayBodyWithPublicCtor(
                const Shape& shape, const Strides& strides, Dtype dtype, Device& device, std::shared_ptr<void> data, int64_t offset)
            : ArrayBody{shape, strides, dtype, device, std::move(data), offset} {}
    };

    std::shared_ptr<ArrayBody> array_body =
            std::make_shared<ArrayBodyWithPublicCtor>(shape, strides, dtype, device, std::move(data), offset);

    if (internal::ArrayBodyLeakTracker* tracker = internal::ArrayBodyLeakDetectionScope::GetGlobalTracker()) {
        // TODO(niboshi): Make thread-safe
        (*tracker)(array_body);
    }

    return array_body;
}

std::shared_ptr<ArrayBody> CreateArrayBody(ArrayBody::Params params) {
    return CreateArrayBody(params.shape, params.strides, params.dtype, params.device, std::move(params.data), params.offset);
}

ArrayBody::ArrayBody(
        const Shape& shape,  // NOLINT(modernize-pass-by-value)
        const Strides& strides,  // NOLINT(modernize-pass-by-value)
        Dtype dtype,
        Device& device,
        std::shared_ptr<void> data,
        int64_t offset)
    : shape_{shape}, strides_{strides}, dtype_{dtype}, device_{device}, data_{std::move(data)}, offset_{offset} {}

ArrayBody::ArrayBody(Params params)
    : ArrayBody{params.shape, params.strides, params.dtype, params.device, std::move(params.data), params.offset} {}

const std::shared_ptr<ArrayNode>& ArrayBody::AddNode(const std::shared_ptr<ArrayBody>& body, std::shared_ptr<ArrayNode> array_node) {
    body->AssertConsistency();

    // The body must be either unset (the array node is being created normally) or dead (the body is being replaced with a fabricated one,
    // as a retained output of backward)
    assert(array_node->weak_body().expired());

    auto it = std::find_if(body->nodes_.begin(), body->nodes_.end(), [&array_node](const std::shared_ptr<ArrayNode>& existing_node) {
        return existing_node->backprop_id() == array_node->backprop_id();
    });
    if (it != body->nodes_.end()) {
        return *it;  // Do nothing and return the existing ArrayNode if found for this graph.
    }

    array_node->weak_body_ = body;

    body->nodes_.emplace_back(std::move(array_node));
    body->grads_.emplace_back(std::make_unique<nonstd::optional<Array>>(nonstd::nullopt));

    body->AssertConsistency();
    return body->nodes_.back();
}

const std::shared_ptr<ArrayNode>& ArrayBody::CreateArrayNode(const std::shared_ptr<ArrayBody>& body, const BackpropId& backprop_id) {
    assert(GetKind(body->dtype()) == DtypeKind::kFloat);
    return AddNode(body, std::make_shared<ArrayNode>(body->shape_, body->dtype_, body->device_, backprop_id));
}

void ArrayBody::AssertConsistency() const {
#ifndef NDEBUG
    // Array with integral dtypes cannot have both array nodes and gradients.
    if (GetKind(dtype()) != DtypeKind::kFloat) {
        assert(nodes_.empty());
        assert(grads_.empty());
    }

    assert(nodes_.size() == grads_.size());
    for (size_t i = 0; i < nodes_.size(); ++i) {
        const std::shared_ptr<ArrayNode>& array_node = nodes_[i];
        const nonstd::optional<Array>& grad = *grads_[i];
        assert(array_node != nullptr);
        assert(this == array_node->weak_body().lock().get());
        if (grad.has_value()) {
            assert(internal::GetArrayBody(*grad) != nullptr);
            assert(grad->shape() == array_node->shape());
            assert(grad->dtype() == array_node->dtype());
            assert(&grad->device() == &array_node->device());
        }
    }
#endif  // NDEBUG
}

nonstd::optional<size_t> ArrayBody::GetNodeIndex(const BackpropId& backprop_id) const {
    for (size_t i = 0; i < nodes_.size(); ++i) {
        if (nodes_[i]->backprop_id() == backprop_id) {
            return i;
        }
    }
    return nonstd::nullopt;
}

void ArrayBody::SetGrad(Array grad, const BackpropId& backprop_id) {
    nonstd::optional<Array>* target_grad = GetGrad(backprop_id);
    assert(target_grad != nullptr);
    internal::SetGrad(*target_grad, std::move(grad), shape_, dtype_, device_);
}

void ArrayBody::AccumulateGrad(Array partial_grad, const BackpropId& backprop_id) {
    nonstd::optional<Array>* target_grad = GetGrad(backprop_id);
    assert(target_grad != nullptr);
    internal::AccumulateGrad(*target_grad, std::move(partial_grad), shape_, dtype_, device_);
}

void ArrayBody::ClearGrad(const BackpropId& backprop_id) {
    nonstd::optional<Array>* grad = GetGrad(backprop_id);
    if (grad == nullptr) {
        throw XchainerError{"Array does not require gradient for backprop id: '", backprop_id, "'."};
    }
    grad->reset();
}

template <typename ThisPtr, typename ReturnType>
ReturnType ArrayBody::GetGradImpl(ThisPtr this_ptr, const BackpropId& backprop_id) {
    nonstd::optional<size_t> i = this_ptr->GetNodeIndex(backprop_id);
    if (!i.has_value()) {
        return nullptr;
    }
    assert(*i < this_ptr->grads_.size());
    return this_ptr->grads_[*i].get();
}

template nonstd::optional<Array>* ArrayBody::GetGradImpl<ArrayBody*, nonstd::optional<Array>*>(ArrayBody*, const BackpropId&);
template const nonstd::optional<Array>* ArrayBody::GetGradImpl<const ArrayBody*, const nonstd::optional<Array>*>(
        const ArrayBody*, const BackpropId&);

}  // namespace internal
}  // namespace xchainer
<commit_msg>Fix English<commit_after>#include "xchainer/array_body.h"

#include <algorithm>
#include <cassert>
#include <cstdint>
#include <memory>
#include <utility>

#include "xchainer/array.h"
#include "xchainer/array_body_leak_detection.h"
#include "xchainer/array_node.h"
#include "xchainer/backward.h"
#include "xchainer/dtype.h"
#include "xchainer/error.h"
#include "xchainer/graph.h"

namespace xchainer {
namespace internal {

std::shared_ptr<ArrayBody> CreateArrayBody(
        const Shape& shape, const Strides& strides, Dtype dtype, Device& device, std::shared_ptr<void> data, int64_t offset) {
    // Trick to use make_shared with private ctor
    struct ArrayBodyWithPublicCtor : ArrayBody {
        ArrayBodyWithPublicCtor(
                const Shape& shape, const Strides& strides, Dtype dtype, Device& device, std::shared_ptr<void> data, int64_t offset)
            : ArrayBody{shape, strides, dtype, device, std::move(data), offset} {}
    };

    std::shared_ptr<ArrayBody> array_body =
            std::make_shared<ArrayBodyWithPublicCtor>(shape, strides, dtype, device, std::move(data), offset);

    if (internal::ArrayBodyLeakTracker* tracker = internal::ArrayBodyLeakDetectionScope::GetGlobalTracker()) {
        // TODO(niboshi): Make thread-safe
        (*tracker)(array_body);
    }

    return array_body;
}

std::shared_ptr<ArrayBody> CreateArrayBody(ArrayBody::Params params) {
    return CreateArrayBody(params.shape, params.strides, params.dtype, params.device, std::move(params.data), params.offset);
}

ArrayBody::ArrayBody(
        const Shape& shape,  // NOLINT(modernize-pass-by-value)
        const Strides& strides,  // NOLINT(modernize-pass-by-value)
        Dtype dtype,
        Device& device,
        std::shared_ptr<void> data,
        int64_t offset)
    : shape_{shape}, strides_{strides}, dtype_{dtype}, device_{device}, data_{std::move(data)}, offset_{offset} {}

ArrayBody::ArrayBody(Params params)
    : ArrayBody{params.shape, params.strides, params.dtype, params.device, std::move(params.data), params.offset} {}

const std::shared_ptr<ArrayNode>& ArrayBody::AddNode(const std::shared_ptr<ArrayBody>& body, std::shared_ptr<ArrayNode> array_node) {
    body->AssertConsistency();

    // The body must be either unset (the array node is being created normally) or dead (the body is being replaced with a fabricated one,
    // as a retained output of backward)
    assert(array_node->weak_body().expired());

    auto it = std::find_if(body->nodes_.begin(), body->nodes_.end(), [&array_node](const std::shared_ptr<ArrayNode>& existing_node) {
        return existing_node->backprop_id() == array_node->backprop_id();
    });
    if (it != body->nodes_.end()) {
        return *it;  // Do nothing and return the existing ArrayNode if found for this graph.
    }

    array_node->weak_body_ = body;

    body->nodes_.emplace_back(std::move(array_node));
    body->grads_.emplace_back(std::make_unique<nonstd::optional<Array>>(nonstd::nullopt));

    body->AssertConsistency();
    return body->nodes_.back();
}

const std::shared_ptr<ArrayNode>& ArrayBody::CreateArrayNode(const std::shared_ptr<ArrayBody>& body, const BackpropId& backprop_id) {
    assert(GetKind(body->dtype()) == DtypeKind::kFloat);
    return AddNode(body, std::make_shared<ArrayNode>(body->shape_, body->dtype_, body->device_, backprop_id));
}

void ArrayBody::AssertConsistency() const {
#ifndef NDEBUG
    // Array with integral dtypes can neither have array nodes nor gradients.
    if (GetKind(dtype()) != DtypeKind::kFloat) {
        assert(nodes_.empty());
        assert(grads_.empty());
    }

    assert(nodes_.size() == grads_.size());
    for (size_t i = 0; i < nodes_.size(); ++i) {
        const std::shared_ptr<ArrayNode>& array_node = nodes_[i];
        const nonstd::optional<Array>& grad = *grads_[i];
        assert(array_node != nullptr);
        assert(this == array_node->weak_body().lock().get());
        if (grad.has_value()) {
            assert(internal::GetArrayBody(*grad) != nullptr);
            assert(grad->shape() == array_node->shape());
            assert(grad->dtype() == array_node->dtype());
            assert(&grad->device() == &array_node->device());
        }
    }
#endif  // NDEBUG
}

nonstd::optional<size_t> ArrayBody::GetNodeIndex(const BackpropId& backprop_id) const {
    for (size_t i = 0; i < nodes_.size(); ++i) {
        if (nodes_[i]->backprop_id() == backprop_id) {
            return i;
        }
    }
    return nonstd::nullopt;
}

void ArrayBody::SetGrad(Array grad, const BackpropId& backprop_id) {
    nonstd::optional<Array>* target_grad = GetGrad(backprop_id);
    assert(target_grad != nullptr);
    internal::SetGrad(*target_grad, std::move(grad), shape_, dtype_, device_);
}

void ArrayBody::AccumulateGrad(Array partial_grad, const BackpropId& backprop_id) {
    nonstd::optional<Array>* target_grad = GetGrad(backprop_id);
    assert(target_grad != nullptr);
    internal::AccumulateGrad(*target_grad, std::move(partial_grad), shape_, dtype_, device_);
}

void ArrayBody::ClearGrad(const BackpropId& backprop_id) {
    nonstd::optional<Array>* grad = GetGrad(backprop_id);
    if (grad == nullptr) {
        throw XchainerError{"Array does not require gradient for backprop id: '", backprop_id, "'."};
    }
    grad->reset();
}

template <typename ThisPtr, typename ReturnType>
ReturnType ArrayBody::GetGradImpl(ThisPtr this_ptr, const BackpropId& backprop_id) {
    nonstd::optional<size_t> i = this_ptr->GetNodeIndex(backprop_id);
    if (!i.has_value()) {
        return nullptr;
    }
    assert(*i < this_ptr->grads_.size());
    return this_ptr->grads_[*i].get();
}

template nonstd::optional<Array>* ArrayBody::GetGradImpl<ArrayBody*, nonstd::optional<Array>*>(ArrayBody*, const BackpropId&);
template const nonstd::optional<Array>* ArrayBody::GetGradImpl<const ArrayBody*, const nonstd::optional<Array>*>(
        const ArrayBody*, const BackpropId&);

}  // namespace internal
}  // namespace xchainer
<|endoftext|>


<commit_before>#include <tweek/CORBA/CorbaManager.h>
#include <vpr/Thread/Thread.h>
#include <vpr/Util/Debug.h>

#include <SliderSubjectImpl.h>
#include <WhiteboardSubjectImpl.h>

/**
 * This application starts the CORBA server for the C++ side of the test.
 */
int main (int argc, char* argv[])
{
   tweek::CorbaManager mgr;

   // The first thing we have to do is initialize the Tweek CORBA Manager.
   // If this fails, we're out of luck.
   try
   {
      if ( mgr.init("corba_test", argc, argv).success() )
      {
         vpr::ReturnStatus status;

         // Once the CORBA Manager is initialized, we need to create a
         // Subject Manager.  This will hold our SliderSubject and our
         // WhiteboardSubject objects.
         try
         {
            status = mgr.createSubjectManager();

            // If we were able to create the Subject Manager, now we register
            // our objects with it.
            if ( status.success() )
            {
               // Add a test informational item to the Subject Manager.
               mgr.getSubjectManager()->addInfoItem("My Value",
                                                    "This is a test");

               // First, create real instances of the C++ objects that will
               // be the CORBA servants.  These must be allocated on the heap.
               networktest::SliderSubjectImpl* slider_subj =
                  new networktest::SliderSubjectImpl();
               networktest::WhiteboardSubjectImpl* whiteboard_subj =
                  new networktest::WhiteboardSubjectImpl();

               // Now we try to register the subjects and give them symbolic,
               // easy-to-remember names.
               try
               {
                  mgr.getSubjectManager()->registerSubject(slider_subj,
                                                           "SliderSubject");
                  mgr.getSubjectManager()->registerSubject(whiteboard_subj,
                                                           "WhiteboardSubject");
               }
               catch (...)
               {
                  vprDEBUG(vprDBG_ALL, vprDBG_CRITICAL_LVL)
                     << "Failed to register subject\n" << vprDEBUG_FLUSH;
               }
            }
         }
         catch (CORBA::Exception& ex)
         {
            vprDEBUG(vprDBG_ALL, vprDBG_CRITICAL_LVL)
               << "Caught an unknown CORBA exception when trying to register!\n"
               << vprDEBUG_FLUSH;
         }

         if ( ! status.success() )
         {
            vprDEBUG(vprDBG_ALL, vprDBG_CRITICAL_LVL)
               << "Failed to register Subject Manager instance\n"
               << vprDEBUG_FLUSH;
         }

         std::cout << "Press 'x' to exit" << std::endl;
         char input;

         // Loop forever so that we can act sort of like a server.
         while ( 1 )
         {
            std::cin >> input;
            if ( input == 'x' )
            {
               break;
            }
            else
            {
               vpr::System::msleep(100);
            }
         }
      }
      else
      {
         vprDEBUG(vprDBG_ALL, vprDBG_CRITICAL_LVL)
            << "CORBA failed to initialize\n" << vprDEBUG_FLUSH;
      }
   }
   catch (...)
   {
      vprDEBUG(vprDBG_ALL, vprDBG_CRITICAL_LVL)
         << "Caught an unknown exception!\n" << vprDEBUG_FLUSH;
   }

   vprDEBUG(vprDBG_ALL, vprDBG_CRITICAL_LVL) << "Exiting\n" << vprDEBUG_FLUSH;

   return 0;
}
<commit_msg>Added missing #include's.  Such sloppy code.  :(<commit_after>#include <iostream>
#include <string>

#include <vpr/vpr.h>
#include <vpr/System.h>
#include <vpr/Thread/Thread.h>
#include <vpr/Util/Debug.h>

#include <tweek/CORBA/CorbaManager.h>

#include <SliderSubjectImpl.h>
#include <WhiteboardSubjectImpl.h>

/**
 * This application starts the CORBA server for the C++ side of the test.
 */
int main (int argc, char* argv[])
{
   tweek::CorbaManager mgr;

   // The first thing we have to do is initialize the Tweek CORBA Manager.
   // If this fails, we're out of luck.
   try
   {
      if ( mgr.init("corba_test", argc, argv).success() )
      {
         vpr::ReturnStatus status;

         // Once the CORBA Manager is initialized, we need to create a
         // Subject Manager.  This will hold our SliderSubject and our
         // WhiteboardSubject objects.
         try
         {
            status = mgr.createSubjectManager();

            // If we were able to create the Subject Manager, now we register
            // our objects with it.
            if ( status.success() )
            {
               // Add a test informational item to the Subject Manager.
               mgr.getSubjectManager()->addInfoItem("My Value",
                                                    "This is a test");

               // First, create real instances of the C++ objects that will
               // be the CORBA servants.  These must be allocated on the heap.
               networktest::SliderSubjectImpl* slider_subj =
                  new networktest::SliderSubjectImpl();
               networktest::WhiteboardSubjectImpl* whiteboard_subj =
                  new networktest::WhiteboardSubjectImpl();

               // Now we try to register the subjects and give them symbolic,
               // easy-to-remember names.
               try
               {
                  mgr.getSubjectManager()->registerSubject(slider_subj,
                                                           "SliderSubject");
                  mgr.getSubjectManager()->registerSubject(whiteboard_subj,
                                                           "WhiteboardSubject");
               }
               catch (...)
               {
                  vprDEBUG(vprDBG_ALL, vprDBG_CRITICAL_LVL)
                     << "Failed to register subject\n" << vprDEBUG_FLUSH;
               }
            }
         }
         catch (CORBA::Exception& ex)
         {
            vprDEBUG(vprDBG_ALL, vprDBG_CRITICAL_LVL)
               << "Caught an unknown CORBA exception when trying to register!\n"
               << vprDEBUG_FLUSH;
         }

         if ( ! status.success() )
         {
            vprDEBUG(vprDBG_ALL, vprDBG_CRITICAL_LVL)
               << "Failed to register Subject Manager instance\n"
               << vprDEBUG_FLUSH;
         }

         std::cout << "Press 'x' to exit" << std::endl;
         char input;

         // Loop forever so that we can act sort of like a server.
         while ( 1 )
         {
            std::cin >> input;
            if ( input == 'x' )
            {
               break;
            }
            else
            {
               vpr::System::msleep(100);
            }
         }
      }
      else
      {
         vprDEBUG(vprDBG_ALL, vprDBG_CRITICAL_LVL)
            << "CORBA failed to initialize\n" << vprDEBUG_FLUSH;
      }
   }
   catch (...)
   {
      vprDEBUG(vprDBG_ALL, vprDBG_CRITICAL_LVL)
         << "Caught an unknown exception!\n" << vprDEBUG_FLUSH;
   }

   vprDEBUG(vprDBG_ALL, vprDBG_CRITICAL_LVL) << "Exiting\n" << vprDEBUG_FLUSH;

   return 0;
}
<|endoftext|>


<commit_before>/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    void deleteNode(ListNode* node) {
        ListNode *tmp = node->next;
        node->next = tmp->next;
        node->val = tmp->val;
        delete tmp;
    }
};
<commit_msg>Update 237.cpp<commit_after>/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    void deleteNode(ListNode* node) {
        ListNode *tmp = node->next;
        node->next = tmp->next;
        node->val = tmp->val;
        delete tmp;
    }
};

<|endoftext|>


<commit_before>/* -*- coding: utf-8; mode: c++; tab-width: 3; indent-tabs-mode: nil -*-

Copyright 2014
Raffaello D. Di Napoli

This file is part of Abaclade.

Abaclade is free software: you can redistribute it and/or modify it under the terms of the GNU
General Public License as published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

Abaclade is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
Public License for more details.

You should have received a copy of the GNU General Public License along with Abaclade. If not, see
<http://www.gnu.org/licenses/>.
--------------------------------------------------------------------------------------------------*/

#ifndef _ABACLADE_RANGE_HXX
#define _ABACLADE_RANGE_HXX

#ifndef _ABACLADE_HXX
   #error "Please #include <abaclade.hxx> before this file"
#endif
#ifdef ABC_CXX_PRAGMA_ONCE
   #pragma once
#endif

////////////////////////////////////////////////////////////////////////////////////////////////////
// abc::range

namespace abc {

/*! Represents an iterable interval of values defined by a beginning and an end, inclusive and
exclusive respectively. */
template <typename T>
class range : public support_explicit_operator_bool<range<T>> {
public:
   //! Iterator for range values.
   class iterator : public std::iterator<std::bidirectional_iterator_tag, T> {
   public:
      /*! Constructor.

      @param t
         Current value.
      */
      explicit iterator(T t) :
         m_t(t) {
      }

      /*! Dereferencing operator.

      @return
         Reference to the current node.
      */
      T operator*() const {
         return m_t;
      }

      /*! Dereferencing member access operator.

      @return
         Pointer to the current value.
      */
      T * operator->() {
         return &m_t;
      }
      T const * operator->() const {
         return &m_t;
      }

      /*! Preincrement operator.

      @return
         *this after it’s moved to the value following the one currently referenced.
      */
      iterator & operator++() {
         ++m_t;
         return *this;
      }

      /*! Postincrement operator.

      @return
         Iterator to the value following the one referenced by this iterator.
      */
      iterator operator++(int) {
         return iterator(m_t++);
      }

      /*! Predecrement operator.

      @return
         *this after it’s moved to the value preceding the one currently referenced.
      */
      iterator & operator--() {
         --m_t;
         return *this;
      }

      /*! Postdecrement operator.

      @return
         Iterator to the value preceding the one referenced by this iterator.
      */
      iterator operator--(int) {
         return iterator(m_t--);
      }

      /*! Equality relational operator.

      @param it
         Object to compare to *this.
      @return
         true if *this has the same value as it, or false otherwise.
      */
      bool operator==(iterator const & it) const {
         return m_t == it.m_t;
      }

      /*! Inequality relational operator.

      @param it
         Object to compare to *this.
      @return
         true if *this has a different value than it, or false otherwise.
      */
      bool operator!=(iterator const & it) const {
         return !operator==(it);
      }

      /*! Returns the underlying iterator type.

      @return
         Pointer to the current node.
      */
      T base() const {
         return m_t;
      }

   private:
      //! Current value.
      T m_t;
   };

   typedef std::reverse_iterator<iterator> reverse_iterator;

public:
   /*! Constructor.

   @param tBegin
      First value in the range.
   @param tEnd
      Value beyond the last one in the range.
   */
   range() :
      m_tBegin(),
      m_tEnd() {
   }
   range(T tBegin, T tEnd) :
      m_tBegin(std::move(tBegin)),
      m_tEnd(std::move(tEnd)) {
   }

   /*! Boolean evaluation operator.

   @return
      true if the range is non-empty, or false if it’s empty.
   */
   explicit_operator_bool() const {
      return m_tBegin != m_tEnd;
   }

   /*! Equality relational operator.

   @param r
      Object to compare to *this.
   @return
      true if *this has the same begin and end as r, or false otherwise.
   */
   bool operator==(range const & r) const {
      return m_tBegin == r.m_tBegin && m_tEnd == r.m_tEnd;
   }

   /*! Inequality relational operator.

   @param r
      Object to compare to *this.
   @return
      true if *this has a different begin and/or end than r, or false otherwise.
   */
   bool operator!=(range const & r) const {
      return !operator==(r);
   }

   /*! Returns an iterator to the start of the range.

   @return
      Iterator to the first value in the range.
   */
   iterator begin() const {
      return iterator(m_tBegin);
   }

   /*! Returns true if the specified value is included in the range.

   @param t
      Value to check for inclusion.
   @return
      true if t is included in [begin(), end()), or false otherwise.
   */
   bool contains(T t) const {
      return t >= m_tBegin && t < m_tEnd;
   }

   /*! Returns an iterator to the end of the range.

   @return
      Value beyond the last in the range.
   */
   iterator end() const {
      return iterator(m_tEnd);
   }

   /*! Returns the count of values included in the range.

   @return
      Count of values.
   */
   std::size_t size() const {
      return m_tBegin < m_tEnd ? static_cast<std::size_t>(m_tEnd - m_tBegin) : 0;
   }

private:
   //! First value in the range.
   T m_tBegin;
   //! Value beyond the last one in the range.
   T m_tEnd;
};

/*! Creates an abc::range by inferring the range type from its arguments.

@param tBegin
   First value in the range.
@param tEnd
   Value beyond the last one in the range.
@return
   Range covering [begin, end).
*/
template <typename T>
range<T> make_range(T tBegin, T tEnd) {
   return range<T>(std::move(tBegin), std::move(tEnd));
}

} //namespace abc

////////////////////////////////////////////////////////////////////////////////////////////////////

#endif //ifndef _ABACLADE_RANGE_HXX
<commit_msg>Use std::move() to initialize abc::range::iterator member in constructor<commit_after>/* -*- coding: utf-8; mode: c++; tab-width: 3; indent-tabs-mode: nil -*-

Copyright 2014
Raffaello D. Di Napoli

This file is part of Abaclade.

Abaclade is free software: you can redistribute it and/or modify it under the terms of the GNU
General Public License as published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

Abaclade is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
Public License for more details.

You should have received a copy of the GNU General Public License along with Abaclade. If not, see
<http://www.gnu.org/licenses/>.
--------------------------------------------------------------------------------------------------*/

#ifndef _ABACLADE_RANGE_HXX
#define _ABACLADE_RANGE_HXX

#ifndef _ABACLADE_HXX
   #error "Please #include <abaclade.hxx> before this file"
#endif
#ifdef ABC_CXX_PRAGMA_ONCE
   #pragma once
#endif

////////////////////////////////////////////////////////////////////////////////////////////////////
// abc::range

namespace abc {

/*! Represents an iterable interval of values defined by a beginning and an end, inclusive and
exclusive respectively. */
template <typename T>
class range : public support_explicit_operator_bool<range<T>> {
public:
   //! Iterator for range values.
   class iterator : public std::iterator<std::bidirectional_iterator_tag, T> {
   public:
      /*! Constructor.

      @param t
         Current value.
      */
      explicit iterator(T t) :
         m_t(std::move(t)) {
      }

      /*! Dereferencing operator.

      @return
         Reference to the current node.
      */
      T operator*() const {
         return m_t;
      }

      /*! Dereferencing member access operator.

      @return
         Pointer to the current value.
      */
      T * operator->() {
         return &m_t;
      }
      T const * operator->() const {
         return &m_t;
      }

      /*! Preincrement operator.

      @return
         *this after it’s moved to the value following the one currently referenced.
      */
      iterator & operator++() {
         ++m_t;
         return *this;
      }

      /*! Postincrement operator.

      @return
         Iterator to the value following the one referenced by this iterator.
      */
      iterator operator++(int) {
         return iterator(m_t++);
      }

      /*! Predecrement operator.

      @return
         *this after it’s moved to the value preceding the one currently referenced.
      */
      iterator & operator--() {
         --m_t;
         return *this;
      }

      /*! Postdecrement operator.

      @return
         Iterator to the value preceding the one referenced by this iterator.
      */
      iterator operator--(int) {
         return iterator(m_t--);
      }

      /*! Equality relational operator.

      @param it
         Object to compare to *this.
      @return
         true if *this has the same value as it, or false otherwise.
      */
      bool operator==(iterator const & it) const {
         return m_t == it.m_t;
      }

      /*! Inequality relational operator.

      @param it
         Object to compare to *this.
      @return
         true if *this has a different value than it, or false otherwise.
      */
      bool operator!=(iterator const & it) const {
         return !operator==(it);
      }

      /*! Returns the underlying iterator type.

      @return
         Pointer to the current node.
      */
      T base() const {
         return m_t;
      }

   private:
      //! Current value.
      T m_t;
   };

   typedef std::reverse_iterator<iterator> reverse_iterator;

public:
   /*! Constructor.

   @param tBegin
      First value in the range.
   @param tEnd
      Value beyond the last one in the range.
   */
   range() :
      m_tBegin(),
      m_tEnd() {
   }
   range(T tBegin, T tEnd) :
      m_tBegin(std::move(tBegin)),
      m_tEnd(std::move(tEnd)) {
   }

   /*! Boolean evaluation operator.

   @return
      true if the range is non-empty, or false if it’s empty.
   */
   explicit_operator_bool() const {
      return m_tBegin != m_tEnd;
   }

   /*! Equality relational operator.

   @param r
      Object to compare to *this.
   @return
      true if *this has the same begin and end as r, or false otherwise.
   */
   bool operator==(range const & r) const {
      return m_tBegin == r.m_tBegin && m_tEnd == r.m_tEnd;
   }

   /*! Inequality relational operator.

   @param r
      Object to compare to *this.
   @return
      true if *this has a different begin and/or end than r, or false otherwise.
   */
   bool operator!=(range const & r) const {
      return !operator==(r);
   }

   /*! Returns an iterator to the start of the range.

   @return
      Iterator to the first value in the range.
   */
   iterator begin() const {
      return iterator(m_tBegin);
   }

   /*! Returns true if the specified value is included in the range.

   @param t
      Value to check for inclusion.
   @return
      true if t is included in [begin(), end()), or false otherwise.
   */
   bool contains(T t) const {
      return t >= m_tBegin && t < m_tEnd;
   }

   /*! Returns an iterator to the end of the range.

   @return
      Value beyond the last in the range.
   */
   iterator end() const {
      return iterator(m_tEnd);
   }

   /*! Returns the count of values included in the range.

   @return
      Count of values.
   */
   std::size_t size() const {
      return m_tBegin < m_tEnd ? static_cast<std::size_t>(m_tEnd - m_tBegin) : 0;
   }

private:
   //! First value in the range.
   T m_tBegin;
   //! Value beyond the last one in the range.
   T m_tEnd;
};

/*! Creates an abc::range by inferring the range type from its arguments.

@param tBegin
   First value in the range.
@param tEnd
   Value beyond the last one in the range.
@return
   Range covering [begin, end).
*/
template <typename T>
range<T> make_range(T tBegin, T tEnd) {
   return range<T>(std::move(tBegin), std::move(tEnd));
}

} //namespace abc

////////////////////////////////////////////////////////////////////////////////////////////////////

#endif //ifndef _ABACLADE_RANGE_HXX
<|endoftext|>


<commit_before>#include <DetectionBasedTracker_jni.h>
#include <opencv2/core/core.hpp>
#include <opencv2/contrib/detection_based_tracker.hpp>

#include <string>
#include <vector>

#include <android/log.h>

#define LOG_TAG "FaceDetection/DetectionBasedTracker"
#define LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__))

using namespace std;
using namespace cv;

inline void vector_Rect_to_Mat(vector<Rect>& v_rect, Mat& mat)
{
    mat = Mat(v_rect, true);
}

JNIEXPORT jlong JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeCreateObject
(JNIEnv * jenv, jclass, jstring jFileName, jint faceSize)
{
    LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeCreateObject enter");
    const char* jnamestr = jenv->GetStringUTFChars(jFileName, NULL);
    string stdFileName(jnamestr);
    jlong result = 0;

    try
    {
        DetectionBasedTracker::Parameters DetectorParams;
        if (faceSize > 0)
            DetectorParams.minObjectSize = faceSize;
        result = (jlong)new DetectionBasedTracker(stdFileName, DetectorParams);
    }
    catch(cv::Exception& e)
    {
        LOGD("nativeCreateObject caught cv::Exception: %s", e.what());
        jclass je = jenv->FindClass("org/opencv/core/CvException");
        if(!je)
            je = jenv->FindClass("java/lang/Exception");
        jenv->ThrowNew(je, e.what());
    }
    catch (...)
    {
        LOGD("nativeCreateObject caught unknown exception");
        jclass je = jenv->FindClass("java/lang/Exception");
        jenv->ThrowNew(je, "Unknown exception in JNI code {highgui::VideoCapture_n_1VideoCapture__()}");
        return 0;
    }

    LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeCreateObject exit");
    return result;
}

JNIEXPORT void JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeDestroyObject
(JNIEnv * jenv, jclass, jlong thiz)
{
    LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeDestroyObject enter");
    try
    {
        if(thiz != 0)
        {
            ((DetectionBasedTracker*)thiz)->stop();
            delete (DetectionBasedTracker*)thiz;
        }
    }
    catch(cv::Exception& e)
    {
        LOGD("nativeestroyObject caught cv::Exception: %s", e.what());
        jclass je = jenv->FindClass("org/opencv/core/CvException");
        if(!je)
            je = jenv->FindClass("java/lang/Exception");
        jenv->ThrowNew(je, e.what());
    }
    catch (...)
    {
        LOGD("nativeDestroyObject caught unknown exception");
        jclass je = jenv->FindClass("java/lang/Exception");
        jenv->ThrowNew(je, "Unknown exception in JNI code {highgui::VideoCapture_n_1VideoCapture__()}");
    }
    LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeDestroyObject exit");
}

JNIEXPORT void JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeStart
(JNIEnv * jenv, jclass, jlong thiz)
{
    LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeStart enter");
    try
    {
        ((DetectionBasedTracker*)thiz)->run();
    }
    catch(cv::Exception& e)
    {
        LOGD("nativeStart caught cv::Exception: %s", e.what());
        jclass je = jenv->FindClass("org/opencv/core/CvException");
        if(!je)
            je = jenv->FindClass("java/lang/Exception");
        jenv->ThrowNew(je, e.what());
    }
    catch (...)
    {
        LOGD("nativeStart caught unknown exception");
        jclass je = jenv->FindClass("java/lang/Exception");
        jenv->ThrowNew(je, "Unknown exception in JNI code {highgui::VideoCapture_n_1VideoCapture__()}");
    }
    LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeStart exit");
}

JNIEXPORT void JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeStop
(JNIEnv * jenv, jclass, jlong thiz)
{
    LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeStop enter");
    try
    {
        ((DetectionBasedTracker*)thiz)->stop();
    }
    catch(cv::Exception& e)
    {
        LOGD("nativeStop caught cv::Exception: %s", e.what());
        jclass je = jenv->FindClass("org/opencv/core/CvException");
        if(!je)
            je = jenv->FindClass("java/lang/Exception");
        jenv->ThrowNew(je, e.what());
    }
    catch (...)
    {
        LOGD("nativeStop caught unknown exception");
        jclass je = jenv->FindClass("java/lang/Exception");
        jenv->ThrowNew(je, "Unknown exception in JNI code {highgui::VideoCapture_n_1VideoCapture__()}");
    }
    LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeStop exit");
}

JNIEXPORT void JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeSetFaceSize
(JNIEnv * jenv, jclass, jlong thiz, jint faceSize)
{
    LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeSetFaceSize enter");
    try
    {
        if (faceSize > 0)
        {
            DetectionBasedTracker::Parameters DetectorParams = \
            ((DetectionBasedTracker*)thiz)->getParameters();
            DetectorParams.minObjectSize = faceSize;
            ((DetectionBasedTracker*)thiz)->setParameters(DetectorParams);
        }
    }
    catch(cv::Exception& e)
    {
        LOGD("nativeStop caught cv::Exception: %s", e.what());
        jclass je = jenv->FindClass("org/opencv/core/CvException");
        if(!je)
            je = jenv->FindClass("java/lang/Exception");
        jenv->ThrowNew(je, e.what());
    }
    catch (...)
    {
        LOGD("nativeSetFaceSize caught unknown exception");
        jclass je = jenv->FindClass("java/lang/Exception");
        jenv->ThrowNew(je, "Unknown exception in JNI code {highgui::VideoCapture_n_1VideoCapture__()}");
    }
    LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeSetFaceSize exit");
}

JNIEXPORT void JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeDetect
(JNIEnv * jenv, jclass, jlong thiz, jlong imageGray, jlong faces)
{
    LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeDetect enter");
    try
    {
        vector<Rect> RectFaces;
        ((DetectionBasedTracker*)thiz)->process(*((Mat*)imageGray));
        ((DetectionBasedTracker*)thiz)->getObjects(RectFaces);
        vector_Rect_to_Mat(RectFaces, *((Mat*)faces));
    }
    catch(cv::Exception& e)
    {
        LOGD("nativeCreateObject caught cv::Exception: %s", e.what());
        jclass je = jenv->FindClass("org/opencv/core/CvException");
        if(!je)
            je = jenv->FindClass("java/lang/Exception");
        jenv->ThrowNew(je, e.what());
    }
    catch (...)
    {
        LOGD("nativeDetect caught unknown exception");
        jclass je = jenv->FindClass("java/lang/Exception");
        jenv->ThrowNew(je, "Unknown exception in JNI code {highgui::VideoCapture_n_1VideoCapture__()}");
    }
    LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeDetect exit");
}
<commit_msg>Invalid copy-passed exception messages in FaceDetect sample for Android fixed.<commit_after>#include <DetectionBasedTracker_jni.h>
#include <opencv2/core/core.hpp>
#include <opencv2/contrib/detection_based_tracker.hpp>

#include <string>
#include <vector>

#include <android/log.h>

#define LOG_TAG "FaceDetection/DetectionBasedTracker"
#define LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__))

using namespace std;
using namespace cv;

inline void vector_Rect_to_Mat(vector<Rect>& v_rect, Mat& mat)
{
    mat = Mat(v_rect, true);
}

JNIEXPORT jlong JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeCreateObject
(JNIEnv * jenv, jclass, jstring jFileName, jint faceSize)
{
    LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeCreateObject enter");
    const char* jnamestr = jenv->GetStringUTFChars(jFileName, NULL);
    string stdFileName(jnamestr);
    jlong result = 0;

    try
    {
        DetectionBasedTracker::Parameters DetectorParams;
        if (faceSize > 0)
            DetectorParams.minObjectSize = faceSize;
        result = (jlong)new DetectionBasedTracker(stdFileName, DetectorParams);
    }
    catch(cv::Exception& e)
    {
        LOGD("nativeCreateObject caught cv::Exception: %s", e.what());
        jclass je = jenv->FindClass("org/opencv/core/CvException");
        if(!je)
            je = jenv->FindClass("java/lang/Exception");
        jenv->ThrowNew(je, e.what());
    }
    catch (...)
    {
        LOGD("nativeCreateObject caught unknown exception");
        jclass je = jenv->FindClass("java/lang/Exception");
        jenv->ThrowNew(je, "Unknown exception in JNI code of DetectionBasedTracker.nativeCreateObject()");
        return 0;
    }

    LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeCreateObject exit");
    return result;
}

JNIEXPORT void JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeDestroyObject
(JNIEnv * jenv, jclass, jlong thiz)
{
    LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeDestroyObject enter");
    try
    {
        if(thiz != 0)
        {
            ((DetectionBasedTracker*)thiz)->stop();
            delete (DetectionBasedTracker*)thiz;
        }
    }
    catch(cv::Exception& e)
    {
        LOGD("nativeestroyObject caught cv::Exception: %s", e.what());
        jclass je = jenv->FindClass("org/opencv/core/CvException");
        if(!je)
            je = jenv->FindClass("java/lang/Exception");
        jenv->ThrowNew(je, e.what());
    }
    catch (...)
    {
        LOGD("nativeDestroyObject caught unknown exception");
        jclass je = jenv->FindClass("java/lang/Exception");
        jenv->ThrowNew(je, "Unknown exception in JNI code of DetectionBasedTracker.nativeDestroyObject()");
    }
    LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeDestroyObject exit");
}

JNIEXPORT void JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeStart
(JNIEnv * jenv, jclass, jlong thiz)
{
    LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeStart enter");
    try
    {
        ((DetectionBasedTracker*)thiz)->run();
    }
    catch(cv::Exception& e)
    {
        LOGD("nativeStart caught cv::Exception: %s", e.what());
        jclass je = jenv->FindClass("org/opencv/core/CvException");
        if(!je)
            je = jenv->FindClass("java/lang/Exception");
        jenv->ThrowNew(je, e.what());
    }
    catch (...)
    {
        LOGD("nativeStart caught unknown exception");
        jclass je = jenv->FindClass("java/lang/Exception");
        jenv->ThrowNew(je, "Unknown exception in JNI code of DetectionBasedTracker.nativeStart()");
    }
    LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeStart exit");
}

JNIEXPORT void JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeStop
(JNIEnv * jenv, jclass, jlong thiz)
{
    LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeStop enter");
    try
    {
        ((DetectionBasedTracker*)thiz)->stop();
    }
    catch(cv::Exception& e)
    {
        LOGD("nativeStop caught cv::Exception: %s", e.what());
        jclass je = jenv->FindClass("org/opencv/core/CvException");
        if(!je)
            je = jenv->FindClass("java/lang/Exception");
        jenv->ThrowNew(je, e.what());
    }
    catch (...)
    {
        LOGD("nativeStop caught unknown exception");
        jclass je = jenv->FindClass("java/lang/Exception");
        jenv->ThrowNew(je, "Unknown exception in JNI code of DetectionBasedTracker.nativeStop()");
    }
    LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeStop exit");
}

JNIEXPORT void JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeSetFaceSize
(JNIEnv * jenv, jclass, jlong thiz, jint faceSize)
{
    LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeSetFaceSize enter");
    try
    {
        if (faceSize > 0)
        {
            DetectionBasedTracker::Parameters DetectorParams = \
            ((DetectionBasedTracker*)thiz)->getParameters();
            DetectorParams.minObjectSize = faceSize;
            ((DetectionBasedTracker*)thiz)->setParameters(DetectorParams);
        }
    }
    catch(cv::Exception& e)
    {
        LOGD("nativeStop caught cv::Exception: %s", e.what());
        jclass je = jenv->FindClass("org/opencv/core/CvException");
        if(!je)
            je = jenv->FindClass("java/lang/Exception");
        jenv->ThrowNew(je, e.what());
    }
    catch (...)
    {
        LOGD("nativeSetFaceSize caught unknown exception");
        jclass je = jenv->FindClass("java/lang/Exception");
        jenv->ThrowNew(je, "Unknown exception in JNI code of DetectionBasedTracker.nativeSetFaceSize()");
    }
    LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeSetFaceSize exit");
}

JNIEXPORT void JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeDetect
(JNIEnv * jenv, jclass, jlong thiz, jlong imageGray, jlong faces)
{
    LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeDetect enter");
    try
    {
        vector<Rect> RectFaces;
        ((DetectionBasedTracker*)thiz)->process(*((Mat*)imageGray));
        ((DetectionBasedTracker*)thiz)->getObjects(RectFaces);
        vector_Rect_to_Mat(RectFaces, *((Mat*)faces));
    }
    catch(cv::Exception& e)
    {
        LOGD("nativeCreateObject caught cv::Exception: %s", e.what());
        jclass je = jenv->FindClass("org/opencv/core/CvException");
        if(!je)
            je = jenv->FindClass("java/lang/Exception");
        jenv->ThrowNew(je, e.what());
    }
    catch (...)
    {
        LOGD("nativeDetect caught unknown exception");
        jclass je = jenv->FindClass("java/lang/Exception");
        jenv->ThrowNew(je, "Unknown exception in JNI code DetectionBasedTracker.nativeDetect()");
    }
    LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeDetect exit");
}
<|endoftext|>


<commit_before>// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.

#include "opendb/db.h"
#include "opendb/lefin.h"
#include "opendb/defin.h"
#include "opendb/defout.h"

#include "Machine.hh"
#include "VerilogWriter.hh"
#include "StaMain.hh"

#include "db_sta/dbSta.hh"
#include "db_sta/MakeDbSta.hh"

#include "resizer/MakeResizer.hh"

#include "dbReadVerilog.hh"
#include "openroad/OpenRoad.hh"
#include "openroad/InitOpenRoad.hh"
#include "InitFlute.hh"

namespace sta {
extern const char *openroad_tcl_inits[];
}

// Swig uses C linkage for init functions.
extern "C" {
extern int Openroad_Init(Tcl_Interp *interp);
extern int Opendbtcl_Init(Tcl_Interp *interp);
extern int Replace_Init(Tcl_Interp *interp);
}

namespace ord {

using odb::dbLib;
using odb::dbDatabase;
using sta::evalTclInit;
using sta::dbSta;
using sta::Resizer;

OpenRoad *OpenRoad::openroad_ = nullptr;

OpenRoad::OpenRoad()
{
  openroad_ = this;
}

OpenRoad::~OpenRoad()
{
  deleteDbVerilogNetwork(verilog_network_);
  deleteDbSta(sta_);
  deleteResizer(resizer_);
  odb::dbDatabase::destroy(db_);
}

sta::dbNetwork *
OpenRoad::getDbNetwork()
{
  return sta_->getDbNetwork();
}

////////////////////////////////////////////////////////////////

void
initOpenRoad(Tcl_Interp *interp,
	     const char *prog_arg)
{
  OpenRoad *openroad = new OpenRoad;
  openroad->init(interp, prog_arg);
}

void
OpenRoad::init(Tcl_Interp *tcl_interp,
	       const char *prog_arg)
{
  tcl_interp_ = tcl_interp;

  // Make components.
  db_ = dbDatabase::create();
  sta_ = makeDbSta();
  verilog_network_ = makeDbVerilogNetwork();
  resizer_ = ord::makeResizer();

  // Init components.
  Openroad_Init(tcl_interp);
  // Import TCL scripts.
  evalTclInit(tcl_interp, sta::openroad_tcl_inits);

  Opendbtcl_Init(tcl_interp);
  initDbSta(this);
  initResizer(this);
  initDbVerilogNetwork(this);
  initFlute(prog_arg);
  Replace_Init(tcl_interp);

  // Import exported commands to global namespace.
  Tcl_Eval(interp, "sta::define_sta_cmds");
  Tcl_Eval(interp, "namespace import sta::*");
}

////////////////////////////////////////////////////////////////

void
OpenRoad::readLef(const char *filename,
		  const char *lib_name,
		  bool make_tech,
		  bool make_library)
{
  odb::lefin lef_reader(db_, false);
  if (make_tech && make_library) {
    dbLib *lib = lef_reader.createTechAndLib(lib_name, filename);
    if (lib)
      sta_->readLefAfter(lib);
  }
  else if (make_tech)
    lef_reader.createTech(filename);
  else if (make_library) {
    dbLib *lib = lef_reader.createLib(lib_name, filename);
    if (lib)
      sta_->readLefAfter(lib);
  }
}

void
OpenRoad::readDef(const char *filename)
{
  odb::defin def_reader(db_);
  std::vector<odb::dbLib *> search_libs;
  for (odb::dbLib *lib : db_->getLibs())
    search_libs.push_back(lib);
  def_reader.createChip(search_libs, filename);
  sta_->readDefAfter();
}

void
OpenRoad::writeDef(const char *filename)
{
  odb::dbChip *chip = db_->getChip();
  if (chip) {
    odb::dbBlock *block = chip->getBlock();
    if (block) {
      odb::defout def_writer;
      def_writer.writeBlock(block, filename);
    }
  }
}

void
OpenRoad::readDb(const char *filename)
{
  FILE *stream = fopen(filename, "r");
  if (stream) {
    db_->read(stream);
    sta_->readDbAfter();
    fclose(stream);
  }
}

void
OpenRoad::writeDb(const char *filename)
{
  FILE *stream = fopen(filename, "w");
  if (stream) {
    db_->write(stream);
    fclose(stream);
  }
}

void
OpenRoad::readVerilog(const char *filename)
{
  dbReadVerilog(filename, verilog_network_);
}

void
OpenRoad::linkDesign(const char *design_name)

{
  dbLinkDesign(design_name, verilog_network_, db_);
  sta_->readDbAfter();
}

void
OpenRoad::writeVerilog(const char *filename,
		       bool sort)
{
  sta::writeVerilog(filename, sort, sta_->network());
}

} // namespace
<commit_msg>OpenRoad::init tcl_interp<commit_after>// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.

#include "opendb/db.h"
#include "opendb/lefin.h"
#include "opendb/defin.h"
#include "opendb/defout.h"

#include "Machine.hh"
#include "VerilogWriter.hh"
#include "StaMain.hh"

#include "db_sta/dbSta.hh"
#include "db_sta/MakeDbSta.hh"

#include "resizer/MakeResizer.hh"

#include "dbReadVerilog.hh"
#include "openroad/OpenRoad.hh"
#include "openroad/InitOpenRoad.hh"
#include "InitFlute.hh"

namespace sta {
extern const char *openroad_tcl_inits[];
}

// Swig uses C linkage for init functions.
extern "C" {
extern int Openroad_Init(Tcl_Interp *interp);
extern int Opendbtcl_Init(Tcl_Interp *interp);
extern int Replace_Init(Tcl_Interp *interp);
}

namespace ord {

using odb::dbLib;
using odb::dbDatabase;
using sta::evalTclInit;
using sta::dbSta;
using sta::Resizer;

OpenRoad *OpenRoad::openroad_ = nullptr;

OpenRoad::OpenRoad()
{
  openroad_ = this;
}

OpenRoad::~OpenRoad()
{
  deleteDbVerilogNetwork(verilog_network_);
  deleteDbSta(sta_);
  deleteResizer(resizer_);
  odb::dbDatabase::destroy(db_);
}

sta::dbNetwork *
OpenRoad::getDbNetwork()
{
  return sta_->getDbNetwork();
}

////////////////////////////////////////////////////////////////

void
initOpenRoad(Tcl_Interp *interp,
	     const char *prog_arg)
{
  OpenRoad *openroad = new OpenRoad;
  openroad->init(interp, prog_arg);
}

void
OpenRoad::init(Tcl_Interp *tcl_interp,
	       const char *prog_arg)
{
  tcl_interp_ = tcl_interp;

  // Make components.
  db_ = dbDatabase::create();
  sta_ = makeDbSta();
  verilog_network_ = makeDbVerilogNetwork();
  resizer_ = ord::makeResizer();

  // Init components.
  Openroad_Init(tcl_interp);
  // Import TCL scripts.
  evalTclInit(tcl_interp, sta::openroad_tcl_inits);

  Opendbtcl_Init(tcl_interp);
  initDbSta(this);
  initResizer(this);
  initDbVerilogNetwork(this);
  initFlute(prog_arg);
  Replace_Init(tcl_interp);

  // Import exported commands to global namespace.
  Tcl_Eval(tcl_interp, "sta::define_sta_cmds");
  Tcl_Eval(tcl_interp, "namespace import sta::*");
}

////////////////////////////////////////////////////////////////

void
OpenRoad::readLef(const char *filename,
		  const char *lib_name,
		  bool make_tech,
		  bool make_library)
{
  odb::lefin lef_reader(db_, false);
  if (make_tech && make_library) {
    dbLib *lib = lef_reader.createTechAndLib(lib_name, filename);
    if (lib)
      sta_->readLefAfter(lib);
  }
  else if (make_tech)
    lef_reader.createTech(filename);
  else if (make_library) {
    dbLib *lib = lef_reader.createLib(lib_name, filename);
    if (lib)
      sta_->readLefAfter(lib);
  }
}

void
OpenRoad::readDef(const char *filename)
{
  odb::defin def_reader(db_);
  std::vector<odb::dbLib *> search_libs;
  for (odb::dbLib *lib : db_->getLibs())
    search_libs.push_back(lib);
  def_reader.createChip(search_libs, filename);
  sta_->readDefAfter();
}

void
OpenRoad::writeDef(const char *filename)
{
  odb::dbChip *chip = db_->getChip();
  if (chip) {
    odb::dbBlock *block = chip->getBlock();
    if (block) {
      odb::defout def_writer;
      def_writer.writeBlock(block, filename);
    }
  }
}

void
OpenRoad::readDb(const char *filename)
{
  FILE *stream = fopen(filename, "r");
  if (stream) {
    db_->read(stream);
    sta_->readDbAfter();
    fclose(stream);
  }
}

void
OpenRoad::writeDb(const char *filename)
{
  FILE *stream = fopen(filename, "w");
  if (stream) {
    db_->write(stream);
    fclose(stream);
  }
}

void
OpenRoad::readVerilog(const char *filename)
{
  dbReadVerilog(filename, verilog_network_);
}

void
OpenRoad::linkDesign(const char *design_name)

{
  dbLinkDesign(design_name, verilog_network_, db_);
  sta_->readDbAfter();
}

void
OpenRoad::writeVerilog(const char *filename,
		       bool sort)
{
  sta::writeVerilog(filename, sort, sta_->network());
}

} // namespace
<|endoftext|>


<commit_before>//===-- driver.cpp - Clang GCC-Compatible Driver --------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This is the entry point to the clang driver; it is a thin wrapper
// for functionality in the Driver clang library.
//
//===----------------------------------------------------------------------===//

#include "clang/Driver/Compilation.h"
#include "clang/Driver/Driver.h"
#include "clang/Driver/Option.h"

#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/Config/config.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/System/Host.h"
#include "llvm/System/Path.h"
#include "llvm/System/Signals.h"
using namespace clang;
using namespace clang::driver;

class DriverDiagnosticPrinter : public DiagnosticClient {
  std::string ProgName;
  llvm::raw_ostream &OS;

public:
  DriverDiagnosticPrinter(const std::string _ProgName,
                          llvm::raw_ostream &_OS)
    : ProgName(_ProgName),
      OS(_OS) {}

  virtual void HandleDiagnostic(Diagnostic::Level DiagLevel,
                                const DiagnosticInfo &Info);
};

void DriverDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level,
                                               const DiagnosticInfo &Info) {
  OS << ProgName << ": ";

  switch (Level) {
  case Diagnostic::Ignored: assert(0 && "Invalid diagnostic type");
  case Diagnostic::Note:    OS << "note: "; break;
  case Diagnostic::Warning: OS << "warning: "; break;
  case Diagnostic::Error:   OS << "error: "; break;
  case Diagnostic::Fatal:   OS << "fatal error: "; break;
  }

  llvm::SmallString<100> OutStr;
  Info.FormatDiagnostic(OutStr);
  OS.write(OutStr.begin(), OutStr.size());
  OS << '\n';
}

llvm::sys::Path GetExecutablePath(const char *Argv0) {
  // This just needs to be some symbol in the binary; C++ doesn't
  // allow taking the address of ::main however.
  void *P = (void*) (intptr_t) GetExecutablePath;
  return llvm::sys::Path::GetMainExecutable(Argv0, P);
}

static const char *SaveStringInSet(std::set<std::string> &SavedStrings,
                                   const std::string &S) {
  return SavedStrings.insert(S).first->c_str();
}

/// ApplyQAOverride - Apply a list of edits to the input argument lists.
///
/// The input string is a space separate list of edits to perform,
/// they are applied in order to the input argument lists. Edits
/// should be one of the following forms:
///
///  '#': Silence information about the changes to the command line arguments.
///
///  '^': Add FOO as a new argument at the beginning of the command line.
///
///  '+': Add FOO as a new argument at the end of the command line.
///
///  's/XXX/YYY/': Replace the literal argument XXX by YYY in the
///  command line.
///
///  'xOPTION': Removes all instances of the literal argument OPTION.
///
///  'XOPTION': Removes all instances of the literal argument OPTION,
///  and the following argument.
///
///  'Ox': Removes all flags matching 'O' or 'O[sz0-9]' and adds 'Ox'
///  at the end of the command line.
///
/// \param OS - The stream to write edit information to.
/// \param Args - The vector of command line arguments.
/// \param Edit - The override command to perform.
/// \param SavedStrings - Set to use for storing string representations.
void ApplyOneQAOverride(llvm::raw_ostream &OS,
                        std::vector<const char*> &Args,
                        const std::string &Edit,
                        std::set<std::string> &SavedStrings) {
  // This does not need to be efficient.

  if (Edit[0] == '^') {
    const char *Str =
      SaveStringInSet(SavedStrings, Edit.substr(1, std::string::npos));
    OS << "### Adding argument " << Str << " at beginning\n";
    Args.insert(Args.begin() + 1, Str);
  } else if (Edit[0] == '+') {
    const char *Str =
      SaveStringInSet(SavedStrings, Edit.substr(1, std::string::npos));
    OS << "### Adding argument " << Str << " at end\n";
    Args.push_back(Str);
  } else if (Edit[0] == 'x' || Edit[0] == 'X') {
    std::string Option = Edit.substr(1, std::string::npos);
    for (unsigned i = 1; i < Args.size();) {
      if (Option == Args[i]) {
        OS << "### Deleting argument " << Args[i] << '\n';
        Args.erase(Args.begin() + i);
        if (Edit[0] == 'X') {
          if (i < Args.size()) {
            OS << "### Deleting argument " << Args[i] << '\n';
            Args.erase(Args.begin() + i);
          } else
            OS << "### Invalid X edit, end of command line!\n";
        }
      } else
        ++i;
    }
  } else if (Edit[0] == 'O') {
    for (unsigned i = 1; i < Args.size();) {
      const char *A = Args[i];
      if (A[0] == '-' && A[1] == 'O' &&
          (A[2] == '\0' ||
           (A[3] == '\0' && (A[2] == 's' || A[2] == 'z' ||
                             ('0' <= A[2] && A[2] <= '9'))))) {
        OS << "### Deleting argument " << Args[i] << '\n';
        Args.erase(Args.begin() + i);
      } else
        ++i;
    }
    OS << "### Adding argument " << Edit << " at end\n";
    Args.push_back(SaveStringInSet(SavedStrings, '-' + Edit));
  } else {
    OS << "### Unrecognized edit: " << Edit << "\n";
  }
}

/// ApplyQAOverride - Apply a comma separate list of edits to the
/// input argument lists. See ApplyOneQAOverride.
void ApplyQAOverride(std::vector<const char*> &Args, const char *OverrideStr,
                     std::set<std::string> &SavedStrings) {
  llvm::raw_ostream *OS = &llvm::errs();

  if (OverrideStr[0] == '#') {
    ++OverrideStr;
    OS = &llvm::nulls();
  }

  *OS << "### QA_OVERRIDE_GCC3_OPTIONS: " << OverrideStr << "\n";

  // This does not need to be efficient.

  const char *S = OverrideStr;
  while (*S) {
    const char *End = ::strchr(S, ' ');
    if (!End)
      End = S + strlen(S);
    if (End != S)
      ApplyOneQAOverride(*OS, Args, std::string(S, End), SavedStrings);
    S = End;
    if (*S != '\0')
      ++S;
  }
}

extern int cc1_main(Diagnostic &Diags,
                    const char **ArgBegin, const char **ArgEnd);

int main(int argc, const char **argv) {
  llvm::sys::PrintStackTraceOnErrorSignal();
  llvm::PrettyStackTraceProgram X(argc, argv);

  llvm::sys::Path Path = GetExecutablePath(argv[0]);
  DriverDiagnosticPrinter DiagClient(Path.getBasename(), llvm::errs());

  Diagnostic Diags(&DiagClient);

  // Dispatch to cc1_main if appropriate.
  if (argc > 1 && llvm::StringRef(argv[1]) == "-cc1")
    return cc1_main(Diags, argv+2, argv+argc);

#ifdef CLANG_IS_PRODUCTION
  bool IsProduction = true;
#else
  bool IsProduction = false;
#endif
  Driver TheDriver(Path.getBasename().c_str(), Path.getDirname().c_str(),
                   llvm::sys::getHostTriple().c_str(),
                   "a.out", IsProduction, Diags);

  // Check for ".*++" or ".*++-[^-]*" to determine if we are a C++
  // compiler. This matches things like "c++", "clang++", and "clang++-1.1".
  //
  // Note that we intentionally want to use argv[0] here, to support "clang++"
  // being a symlink.
  std::string ProgName(llvm::sys::Path(argv[0]).getBasename());
  if (llvm::StringRef(ProgName).endswith("++") ||
      llvm::StringRef(ProgName).rsplit('-').first.endswith("++"))
    TheDriver.CCCIsCXX = true;

  llvm::OwningPtr<Compilation> C;

  // Handle QA_OVERRIDE_GCC3_OPTIONS and CCC_ADD_ARGS, used for editing a
  // command line behind the scenes.
  std::set<std::string> SavedStrings;
  if (const char *OverrideStr = ::getenv("QA_OVERRIDE_GCC3_OPTIONS")) {
    // FIXME: Driver shouldn't take extra initial argument.
    std::vector<const char*> StringPointers(argv, argv + argc);

    ApplyQAOverride(StringPointers, OverrideStr, SavedStrings);

    C.reset(TheDriver.BuildCompilation(StringPointers.size(),
                                       &StringPointers[0]));
  } else if (const char *Cur = ::getenv("CCC_ADD_ARGS")) {
    std::vector<const char*> StringPointers;

    // FIXME: Driver shouldn't take extra initial argument.
    StringPointers.push_back(argv[0]);

    for (;;) {
      const char *Next = strchr(Cur, ',');

      if (Next) {
        StringPointers.push_back(SaveStringInSet(SavedStrings,
                                                 std::string(Cur, Next)));
        Cur = Next + 1;
      } else {
        if (*Cur != '\0')
          StringPointers.push_back(SaveStringInSet(SavedStrings, Cur));
        break;
      }
    }

    StringPointers.insert(StringPointers.end(), argv + 1, argv + argc);

    C.reset(TheDriver.BuildCompilation(StringPointers.size(),
                                       &StringPointers[0]));
  } else
    C.reset(TheDriver.BuildCompilation(argc, argv));

  int Res = 0;
  if (C.get())
    Res = TheDriver.ExecuteCompilation(*C);

  llvm::llvm_shutdown();

  return Res;
}

<commit_msg>Add a workaround to silence a bogus g++-4.4 -pedantic warning.<commit_after>//===-- driver.cpp - Clang GCC-Compatible Driver --------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This is the entry point to the clang driver; it is a thin wrapper
// for functionality in the Driver clang library.
//
//===----------------------------------------------------------------------===//

#include "clang/Driver/Compilation.h"
#include "clang/Driver/Driver.h"
#include "clang/Driver/Option.h"

#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/Config/config.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/System/Host.h"
#include "llvm/System/Path.h"
#include "llvm/System/Signals.h"
using namespace clang;
using namespace clang::driver;

class DriverDiagnosticPrinter : public DiagnosticClient {
  std::string ProgName;
  llvm::raw_ostream &OS;

public:
  DriverDiagnosticPrinter(const std::string _ProgName,
                          llvm::raw_ostream &_OS)
    : ProgName(_ProgName),
      OS(_OS) {}

  virtual void HandleDiagnostic(Diagnostic::Level DiagLevel,
                                const DiagnosticInfo &Info);
};

void DriverDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level,
                                               const DiagnosticInfo &Info) {
  OS << ProgName << ": ";

  switch (Level) {
  case Diagnostic::Ignored: assert(0 && "Invalid diagnostic type");
  case Diagnostic::Note:    OS << "note: "; break;
  case Diagnostic::Warning: OS << "warning: "; break;
  case Diagnostic::Error:   OS << "error: "; break;
  case Diagnostic::Fatal:   OS << "fatal error: "; break;
  }

  llvm::SmallString<100> OutStr;
  Info.FormatDiagnostic(OutStr);
  OS.write(OutStr.begin(), OutStr.size());
  OS << '\n';
}

llvm::sys::Path GetExecutablePath(const char *Argv0) {
  // This just needs to be some symbol in the binary; C++ doesn't
  // allow taking the address of ::main however.
  void *P = (void*) (intptr_t) GetExecutablePath;
  return llvm::sys::Path::GetMainExecutable(Argv0, P);
}

static const char *SaveStringInSet(std::set<std::string> &SavedStrings,
                                   const std::string &S) {
  return SavedStrings.insert(S).first->c_str();
}

/// ApplyQAOverride - Apply a list of edits to the input argument lists.
///
/// The input string is a space separate list of edits to perform,
/// they are applied in order to the input argument lists. Edits
/// should be one of the following forms:
///
///  '#': Silence information about the changes to the command line arguments.
///
///  '^': Add FOO as a new argument at the beginning of the command line.
///
///  '+': Add FOO as a new argument at the end of the command line.
///
///  's/XXX/YYY/': Replace the literal argument XXX by YYY in the
///  command line.
///
///  'xOPTION': Removes all instances of the literal argument OPTION.
///
///  'XOPTION': Removes all instances of the literal argument OPTION,
///  and the following argument.
///
///  'Ox': Removes all flags matching 'O' or 'O[sz0-9]' and adds 'Ox'
///  at the end of the command line.
///
/// \param OS - The stream to write edit information to.
/// \param Args - The vector of command line arguments.
/// \param Edit - The override command to perform.
/// \param SavedStrings - Set to use for storing string representations.
void ApplyOneQAOverride(llvm::raw_ostream &OS,
                        std::vector<const char*> &Args,
                        const std::string &Edit,
                        std::set<std::string> &SavedStrings) {
  // This does not need to be efficient.

  if (Edit[0] == '^') {
    const char *Str =
      SaveStringInSet(SavedStrings, Edit.substr(1, std::string::npos));
    OS << "### Adding argument " << Str << " at beginning\n";
    Args.insert(Args.begin() + 1, Str);
  } else if (Edit[0] == '+') {
    const char *Str =
      SaveStringInSet(SavedStrings, Edit.substr(1, std::string::npos));
    OS << "### Adding argument " << Str << " at end\n";
    Args.push_back(Str);
  } else if (Edit[0] == 'x' || Edit[0] == 'X') {
    std::string Option = Edit.substr(1, std::string::npos);
    for (unsigned i = 1; i < Args.size();) {
      if (Option == Args[i]) {
        OS << "### Deleting argument " << Args[i] << '\n';
        Args.erase(Args.begin() + i);
        if (Edit[0] == 'X') {
          if (i < Args.size()) {
            OS << "### Deleting argument " << Args[i] << '\n';
            Args.erase(Args.begin() + i);
          } else
            OS << "### Invalid X edit, end of command line!\n";
        }
      } else
        ++i;
    }
  } else if (Edit[0] == 'O') {
    for (unsigned i = 1; i < Args.size();) {
      const char *A = Args[i];
      if (A[0] == '-' && A[1] == 'O' &&
          (A[2] == '\0' ||
           (A[3] == '\0' && (A[2] == 's' || A[2] == 'z' ||
                             ('0' <= A[2] && A[2] <= '9'))))) {
        OS << "### Deleting argument " << Args[i] << '\n';
        Args.erase(Args.begin() + i);
      } else
        ++i;
    }
    OS << "### Adding argument " << Edit << " at end\n";
    Args.push_back(SaveStringInSet(SavedStrings, '-' + Edit));
  } else {
    OS << "### Unrecognized edit: " << Edit << "\n";
  }
}

/// ApplyQAOverride - Apply a comma separate list of edits to the
/// input argument lists. See ApplyOneQAOverride.
void ApplyQAOverride(std::vector<const char*> &Args, const char *OverrideStr,
                     std::set<std::string> &SavedStrings) {
  llvm::raw_ostream *OS = &llvm::errs();

  if (OverrideStr[0] == '#') {
    ++OverrideStr;
    OS = &llvm::nulls();
  }

  *OS << "### QA_OVERRIDE_GCC3_OPTIONS: " << OverrideStr << "\n";

  // This does not need to be efficient.

  const char *S = OverrideStr;
  while (*S) {
    const char *End = ::strchr(S, ' ');
    if (!End)
      End = S + strlen(S);
    if (End != S)
      ApplyOneQAOverride(*OS, Args, std::string(S, End), SavedStrings);
    S = End;
    if (*S != '\0')
      ++S;
  }
}

extern int cc1_main(Diagnostic &Diags,
                    const char **ArgBegin, const char **ArgEnd);

int main(int argc, const char **argv) {
  llvm::sys::PrintStackTraceOnErrorSignal();
  llvm::PrettyStackTraceProgram X(argc, argv);

  llvm::sys::Path Path = GetExecutablePath(argv[0]);
  DriverDiagnosticPrinter DiagClient(Path.getBasename(), llvm::errs());

  Diagnostic Diags(&DiagClient);

  // Dispatch to cc1_main if appropriate.
  if (argc > 1 && llvm::StringRef(argv[1]) == "-cc1")
    return cc1_main(Diags, argv+2, argv+argc);

#ifdef CLANG_IS_PRODUCTION
  bool IsProduction = true;
#else
  bool IsProduction = false;
#endif
  Driver TheDriver(Path.getBasename().c_str(), Path.getDirname().c_str(),
                   llvm::sys::getHostTriple().c_str(),
                   "a.out", IsProduction, Diags);

  // Check for ".*++" or ".*++-[^-]*" to determine if we are a C++
  // compiler. This matches things like "c++", "clang++", and "clang++-1.1".
  //
  // Note that we intentionally want to use argv[0] here, to support "clang++"
  // being a symlink.
  //
  // We use *argv instead of argv[0] to work around a bogus g++ warning.
  std::string ProgName(llvm::sys::Path(*argv).getBasename());
  if (llvm::StringRef(ProgName).endswith("++") ||
      llvm::StringRef(ProgName).rsplit('-').first.endswith("++"))
    TheDriver.CCCIsCXX = true;

  llvm::OwningPtr<Compilation> C;

  // Handle QA_OVERRIDE_GCC3_OPTIONS and CCC_ADD_ARGS, used for editing a
  // command line behind the scenes.
  std::set<std::string> SavedStrings;
  if (const char *OverrideStr = ::getenv("QA_OVERRIDE_GCC3_OPTIONS")) {
    // FIXME: Driver shouldn't take extra initial argument.
    std::vector<const char*> StringPointers(argv, argv + argc);

    ApplyQAOverride(StringPointers, OverrideStr, SavedStrings);

    C.reset(TheDriver.BuildCompilation(StringPointers.size(),
                                       &StringPointers[0]));
  } else if (const char *Cur = ::getenv("CCC_ADD_ARGS")) {
    std::vector<const char*> StringPointers;

    // FIXME: Driver shouldn't take extra initial argument.
    StringPointers.push_back(argv[0]);

    for (;;) {
      const char *Next = strchr(Cur, ',');

      if (Next) {
        StringPointers.push_back(SaveStringInSet(SavedStrings,
                                                 std::string(Cur, Next)));
        Cur = Next + 1;
      } else {
        if (*Cur != '\0')
          StringPointers.push_back(SaveStringInSet(SavedStrings, Cur));
        break;
      }
    }

    StringPointers.insert(StringPointers.end(), argv + 1, argv + argc);

    C.reset(TheDriver.BuildCompilation(StringPointers.size(),
                                       &StringPointers[0]));
  } else
    C.reset(TheDriver.BuildCompilation(argc, argv));

  int Res = 0;
  if (C.get())
    Res = TheDriver.ExecuteCompilation(*C);

  llvm::llvm_shutdown();

  return Res;
}

<|endoftext|>