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

  Program:   Visualization Toolkit
  Module:    vtkContourWidget.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 "vtkContourWidget.h"
#include "vtkOrientedGlyphContourRepresentation.h"
#include "vtkCommand.h"
#include "vtkCallbackCommand.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkObjectFactory.h"
#include "vtkRenderer.h"
#include "vtkWidgetCallbackMapper.h"
#include "vtkSphereSource.h"
#include "vtkProperty.h"
#include "vtkEvent.h"
#include "vtkWidgetEvent.h"

#include <vtkstd/vector>
#include <vtkstd/set>
#include <vtkstd/algorithm>
#include <vtkstd/iterator>

vtkCxxRevisionMacro(vtkContourWidget, "1.3");
vtkStandardNewMacro(vtkContourWidget);

//----------------------------------------------------------------------
vtkContourWidget::vtkContourWidget()
{
  this->ManagesCursor = 0;

  this->WidgetState = vtkContourWidget::Start;
  this->CurrentHandle = 0;

  // These are the event callbacks supported by this widget
  this->CallbackMapper->SetCallbackMethod(vtkCommand::LeftButtonPressEvent,
                                          vtkWidgetEvent::Select,
                                          this, vtkContourWidget::SelectAction);
  this->CallbackMapper->SetCallbackMethod(vtkCommand::RightButtonPressEvent,
                                          vtkWidgetEvent::AddFinalPoint,
                                          this, vtkContourWidget::AddFinalPointAction);
  this->CallbackMapper->SetCallbackMethod(vtkCommand::MouseMoveEvent,
                                          vtkWidgetEvent::Move,
                                          this, vtkContourWidget::MoveAction);
  this->CallbackMapper->SetCallbackMethod(vtkCommand::LeftButtonReleaseEvent,
                                          vtkWidgetEvent::EndSelect,
                                          this, vtkContourWidget::EndSelectAction);
  this->CallbackMapper->SetCallbackMethod(vtkCommand::KeyPressEvent,
                                          vtkEvent::NoModifier, 46, 1, NULL,
                                          vtkWidgetEvent::Delete,
                                          this, vtkContourWidget::DeleteAction);

  this->CreateDefaultRepresentation();

}

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

//----------------------------------------------------------------------
void vtkContourWidget::CreateDefaultRepresentation()
{
  if ( ! this->WidgetRep )
    {
    vtkOrientedGlyphContourRepresentation *rep =
      vtkOrientedGlyphContourRepresentation::New();

    this->WidgetRep = rep;

    vtkSphereSource *ss = vtkSphereSource::New();
    ss->SetRadius(0.5);
    rep->SetActiveCursorShape( ss->GetOutput() );
    ss->Delete();

    rep->GetProperty()->SetColor(.25,1.0,.25);

    rep->GetActiveProperty()->SetRepresentationToSurface();
    rep->GetActiveProperty()->SetAmbient(0.1);
    rep->GetActiveProperty()->SetDiffuse(0.9);
    rep->GetActiveProperty()->SetSpecular(0.0);
    }
}

//----------------------------------------------------------------------
void vtkContourWidget::ClearContour()
{
}

//----------------------------------------------------------------------
void vtkContourWidget::SetEnabled(int enabling)
{
  // The handle widgets are not actually enabled until they are placed.
  // The handle widgets take their representation from the vtkContourRepresentation.
  if ( enabling )
    {
    if ( this->WidgetState == vtkContourWidget::Start )
      {
      reinterpret_cast<vtkContourRepresentation*>(this->WidgetRep)->VisibilityOff();
      }
    else
      {
      reinterpret_cast<vtkContourRepresentation*>(this->WidgetRep)->VisibilityOn();
      }
    }

  this->Superclass::SetEnabled(enabling);
}

// The following methods are the callbacks that the measure widget responds to.
//-------------------------------------------------------------------------
void vtkContourWidget::SelectAction(vtkAbstractWidget *w)
{
  vtkContourWidget *self = reinterpret_cast<vtkContourWidget*>(w);
  vtkContourRepresentation *rep =
    reinterpret_cast<vtkContourRepresentation*>(self->WidgetRep);

  int X = self->Interactor->GetEventPosition()[0];
  int Y = self->Interactor->GetEventPosition()[1];
  double pos[2];
  pos[0] = X;
  pos[1] = Y;

  switch ( self->WidgetState )
    {
    case vtkContourWidget::Start:
    case vtkContourWidget::Define:
      self->AddNode();
      break;
    case vtkContourWidget::Manipulate:
      if ( rep->ActivateNode(X,Y) )
        {
        self->StartInteraction();
        rep->SetCurrentOperationToTranslate();
        rep->StartWidgetInteraction(pos);
        self->EventCallbackCommand->SetAbortFlag(1);
        }
      else if ( rep->AddNodeOnContour( X, Y ) )
        {
        if ( rep->ActivateNode(X,Y) )
          {
          rep->SetCurrentOperationToTranslate();
          rep->StartWidgetInteraction(pos);
          }
        self->EventCallbackCommand->SetAbortFlag(1);
        }
      break;
    }

  if ( rep->GetNeedToRender() )
    {
    self->Render();
    rep->NeedToRenderOff();
    }
}

//-------------------------------------------------------------------------
void vtkContourWidget::AddFinalPointAction(vtkAbstractWidget *w)
{
  vtkContourWidget *self = reinterpret_cast<vtkContourWidget*>(w);
  vtkContourRepresentation *rep =
    reinterpret_cast<vtkContourRepresentation*>(self->WidgetRep);

  int X = self->Interactor->GetEventPosition()[0];
  int Y = self->Interactor->GetEventPosition()[1];
  double pos[2];
  pos[0] = X;
  pos[1] = Y;

  if ( self->WidgetState ==  vtkContourWidget::Define &&
       rep->GetNumberOfNodes() >= 1 )
    {
    self->AddNode();
    self->WidgetState = vtkContourWidget::Manipulate;
    self->EventCallbackCommand->SetAbortFlag(1);
    }

  if ( rep->GetNeedToRender() )
    {
    self->Render();
    rep->NeedToRenderOff();
    }
}

//------------------------------------------------------------------------
void vtkContourWidget::AddNode()
{
  int X = this->Interactor->GetEventPosition()[0];
  int Y = this->Interactor->GetEventPosition()[1];

  // If the rep already has at least 2 nodes, check how close we are to
  // the first
  if ( reinterpret_cast<vtkContourRepresentation*>(this->WidgetRep)->
       GetNumberOfNodes() > 1 )
    {
    int pixelTolerance2 =
      reinterpret_cast<vtkContourRepresentation*>(this->WidgetRep)->
      GetPixelTolerance();
    pixelTolerance2 *= pixelTolerance2;

    double displayPos[2];
    if ( !reinterpret_cast<vtkContourRepresentation*>(this->WidgetRep)->
         GetNthNodeDisplayPosition( 0, displayPos ) )
      {
      vtkErrorMacro("Can't get first node display position!");
      return;
      }

    if ( (X - displayPos[0]) * (X - displayPos[0]) +
         (Y - displayPos[1]) * (Y - displayPos[1]) <
         pixelTolerance2 )
      {
      // yes - we have made a loop. Stop defining and switch to
      // manipulate mode
      this->WidgetState = vtkContourWidget::Manipulate;
      reinterpret_cast<vtkContourRepresentation*>(this->WidgetRep)->ClosedLoopOn();
      this->EventCallbackCommand->SetAbortFlag(1);
      return;
      }
    }

  if ( reinterpret_cast<vtkContourRepresentation*>(this->WidgetRep)->
       AddNodeAtDisplayPosition( X, Y ) )
    {
    this->WidgetState = vtkContourWidget::Define;
    reinterpret_cast<vtkContourRepresentation*>(this->WidgetRep)->VisibilityOn();
    this->EventCallbackCommand->SetAbortFlag(1);
    }
}

//-------------------------------------------------------------------------
void vtkContourWidget::DeleteAction(vtkAbstractWidget *w)
{
  vtkContourWidget *self = reinterpret_cast<vtkContourWidget*>(w);

  if ( self->WidgetState == vtkContourWidget::Start )
    {
    return;
    }

  vtkContourRepresentation *rep =
    reinterpret_cast<vtkContourRepresentation*>(self->WidgetRep);

  if ( self->WidgetState == vtkContourWidget::Define )
    {
    rep->DeleteLastNode();
    }
  else
    {
    int X = self->Interactor->GetEventPosition()[0];
    int Y = self->Interactor->GetEventPosition()[1];
    rep->ActivateNode( X, Y );
    rep->DeleteActiveNode();
    rep->ActivateNode( X, Y );
    if ( rep->GetNumberOfNodes() < 3 )
      {
      rep->ClosedLoopOff();
      self->WidgetState = vtkContourWidget::Define;
      }
    }

  if ( rep->GetNeedToRender() )
    {
    self->Render();
    rep->NeedToRenderOff();
    }
}

//-------------------------------------------------------------------------
void vtkContourWidget::MoveAction(vtkAbstractWidget *w)
{
  vtkContourWidget *self = reinterpret_cast<vtkContourWidget*>(w);

  if ( self->WidgetState == vtkContourWidget::Start ||
       self->WidgetState == vtkContourWidget::Define )
    {
    return;
    }

  int X = self->Interactor->GetEventPosition()[0];
  int Y = self->Interactor->GetEventPosition()[1];
  vtkContourRepresentation *rep =
    reinterpret_cast<vtkContourRepresentation*>(self->WidgetRep);

  if ( rep->GetCurrentOperation() == vtkContourRepresentation::Inactive )
    {
    reinterpret_cast<vtkContourRepresentation*>(self->WidgetRep)->
      ComputeInteractionState( X, Y );
    reinterpret_cast<vtkContourRepresentation*>(self->WidgetRep)->
      ActivateNode( X, Y );
    }
  else
    {
    double pos[2];
    pos[0] = X;
    pos[1] = Y;
    self->WidgetRep->WidgetInteraction(pos);
    }

  self->Interaction();

  if ( self->WidgetRep->GetNeedToRender() )
    {
    self->Render();
    self->WidgetRep->NeedToRenderOff();
    }
}

//-------------------------------------------------------------------------
void vtkContourWidget::EndSelectAction(vtkAbstractWidget *w)
{
  vtkContourWidget *self = reinterpret_cast<vtkContourWidget*>(w);
  vtkContourRepresentation *rep =
    reinterpret_cast<vtkContourRepresentation*>(self->WidgetRep);

  // Do nothing if inactive
  if ( rep->GetCurrentOperation() == vtkContourRepresentation::Inactive )
    {
    return;
    }

  rep->SetCurrentOperationToInactive();
  self->EventCallbackCommand->SetAbortFlag(1);
  self->EndInteraction();

  if ( self->WidgetRep->GetNeedToRender() )
    {
    self->Render();
    self->WidgetRep->NeedToRenderOff();
    }
}

// These are callbacks that are active when the user is manipulating the
// handles of the measure widget.
//----------------------------------------------------------------------
void vtkContourWidget::StartInteraction()
{
  this->Superclass::StartInteraction();
  this->InvokeEvent(vtkCommand::StartInteractionEvent,NULL);
}

//----------------------------------------------------------------------
void vtkContourWidget::Interaction()
{
  this->InvokeEvent(vtkCommand::InteractionEvent,NULL);
}

//----------------------------------------------------------------------
void vtkContourWidget::EndInteraction()
{
  this->Superclass::EndInteraction();
  this->InvokeEvent(vtkCommand::EndInteractionEvent,NULL);
}

//----------------------------------------------------------------------
void vtkContourWidget::PrintSelf(ostream& os, vtkIndent indent)
{
  //Superclass typedef defined in vtkTypeMacro() found in vtkSetGet.h
  this->Superclass::PrintSelf(os,indent);

}
<commit_msg>BUG: Removed warnings<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkContourWidget.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 "vtkContourWidget.h"
#include "vtkOrientedGlyphContourRepresentation.h"
#include "vtkCommand.h"
#include "vtkCallbackCommand.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkObjectFactory.h"
#include "vtkRenderer.h"
#include "vtkWidgetCallbackMapper.h"
#include "vtkSphereSource.h"
#include "vtkProperty.h"
#include "vtkEvent.h"
#include "vtkWidgetEvent.h"

#include <vtkstd/vector>
#include <vtkstd/set>
#include <vtkstd/algorithm>
#include <vtkstd/iterator>

vtkCxxRevisionMacro(vtkContourWidget, "1.4");
vtkStandardNewMacro(vtkContourWidget);

//----------------------------------------------------------------------
vtkContourWidget::vtkContourWidget()
{
  this->ManagesCursor = 0;

  this->WidgetState = vtkContourWidget::Start;
  this->CurrentHandle = 0;

  // These are the event callbacks supported by this widget
  this->CallbackMapper->SetCallbackMethod(vtkCommand::LeftButtonPressEvent,
                                          vtkWidgetEvent::Select,
                                          this, vtkContourWidget::SelectAction);
  this->CallbackMapper->SetCallbackMethod(vtkCommand::RightButtonPressEvent,
                                          vtkWidgetEvent::AddFinalPoint,
                                          this, vtkContourWidget::AddFinalPointAction);
  this->CallbackMapper->SetCallbackMethod(vtkCommand::MouseMoveEvent,
                                          vtkWidgetEvent::Move,
                                          this, vtkContourWidget::MoveAction);
  this->CallbackMapper->SetCallbackMethod(vtkCommand::LeftButtonReleaseEvent,
                                          vtkWidgetEvent::EndSelect,
                                          this, vtkContourWidget::EndSelectAction);
  this->CallbackMapper->SetCallbackMethod(vtkCommand::KeyPressEvent,
                                          vtkEvent::NoModifier, 46, 1, NULL,
                                          vtkWidgetEvent::Delete,
                                          this, vtkContourWidget::DeleteAction);

  this->CreateDefaultRepresentation();

}

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

//----------------------------------------------------------------------
void vtkContourWidget::CreateDefaultRepresentation()
{
  if ( ! this->WidgetRep )
    {
    vtkOrientedGlyphContourRepresentation *rep =
      vtkOrientedGlyphContourRepresentation::New();

    this->WidgetRep = rep;

    vtkSphereSource *ss = vtkSphereSource::New();
    ss->SetRadius(0.5);
    rep->SetActiveCursorShape( ss->GetOutput() );
    ss->Delete();

    rep->GetProperty()->SetColor(.25,1.0,.25);

    rep->GetActiveProperty()->SetRepresentationToSurface();
    rep->GetActiveProperty()->SetAmbient(0.1);
    rep->GetActiveProperty()->SetDiffuse(0.9);
    rep->GetActiveProperty()->SetSpecular(0.0);
    }
}

//----------------------------------------------------------------------
void vtkContourWidget::ClearContour()
{
}

//----------------------------------------------------------------------
void vtkContourWidget::SetEnabled(int enabling)
{
  // The handle widgets are not actually enabled until they are placed.
  // The handle widgets take their representation from the vtkContourRepresentation.
  if ( enabling )
    {
    if ( this->WidgetState == vtkContourWidget::Start )
      {
      reinterpret_cast<vtkContourRepresentation*>(this->WidgetRep)->VisibilityOff();
      }
    else
      {
      reinterpret_cast<vtkContourRepresentation*>(this->WidgetRep)->VisibilityOn();
      }
    }

  this->Superclass::SetEnabled(enabling);
}

// The following methods are the callbacks that the measure widget responds to.
//-------------------------------------------------------------------------
void vtkContourWidget::SelectAction(vtkAbstractWidget *w)
{
  vtkContourWidget *self = reinterpret_cast<vtkContourWidget*>(w);
  vtkContourRepresentation *rep =
    reinterpret_cast<vtkContourRepresentation*>(self->WidgetRep);

  int X = self->Interactor->GetEventPosition()[0];
  int Y = self->Interactor->GetEventPosition()[1];
  double pos[2];
  pos[0] = X;
  pos[1] = Y;

  switch ( self->WidgetState )
    {
    case vtkContourWidget::Start:
    case vtkContourWidget::Define:
      self->AddNode();
      break;
    case vtkContourWidget::Manipulate:
      if ( rep->ActivateNode(X,Y) )
        {
        self->StartInteraction();
        rep->SetCurrentOperationToTranslate();
        rep->StartWidgetInteraction(pos);
        self->EventCallbackCommand->SetAbortFlag(1);
        }
      else if ( rep->AddNodeOnContour( X, Y ) )
        {
        if ( rep->ActivateNode(X,Y) )
          {
          rep->SetCurrentOperationToTranslate();
          rep->StartWidgetInteraction(pos);
          }
        self->EventCallbackCommand->SetAbortFlag(1);
        }
      break;
    }

  if ( rep->GetNeedToRender() )
    {
    self->Render();
    rep->NeedToRenderOff();
    }
}

//-------------------------------------------------------------------------
void vtkContourWidget::AddFinalPointAction(vtkAbstractWidget *w)
{
  vtkContourWidget *self = reinterpret_cast<vtkContourWidget*>(w);
  vtkContourRepresentation *rep =
    reinterpret_cast<vtkContourRepresentation*>(self->WidgetRep);

  if ( self->WidgetState ==  vtkContourWidget::Define &&
       rep->GetNumberOfNodes() >= 1 )
    {
    self->AddNode();
    self->WidgetState = vtkContourWidget::Manipulate;
    self->EventCallbackCommand->SetAbortFlag(1);
    }

  if ( rep->GetNeedToRender() )
    {
    self->Render();
    rep->NeedToRenderOff();
    }
}

//------------------------------------------------------------------------
void vtkContourWidget::AddNode()
{
  int X = this->Interactor->GetEventPosition()[0];
  int Y = this->Interactor->GetEventPosition()[1];

  // If the rep already has at least 2 nodes, check how close we are to
  // the first
  if ( reinterpret_cast<vtkContourRepresentation*>(this->WidgetRep)->
       GetNumberOfNodes() > 1 )
    {
    int pixelTolerance2 =
      reinterpret_cast<vtkContourRepresentation*>(this->WidgetRep)->
      GetPixelTolerance();
    pixelTolerance2 *= pixelTolerance2;

    double displayPos[2];
    if ( !reinterpret_cast<vtkContourRepresentation*>(this->WidgetRep)->
         GetNthNodeDisplayPosition( 0, displayPos ) )
      {
      vtkErrorMacro("Can't get first node display position!");
      return;
      }

    if ( (X - displayPos[0]) * (X - displayPos[0]) +
         (Y - displayPos[1]) * (Y - displayPos[1]) <
         pixelTolerance2 )
      {
      // yes - we have made a loop. Stop defining and switch to
      // manipulate mode
      this->WidgetState = vtkContourWidget::Manipulate;
      reinterpret_cast<vtkContourRepresentation*>(this->WidgetRep)->ClosedLoopOn();
      this->EventCallbackCommand->SetAbortFlag(1);
      return;
      }
    }

  if ( reinterpret_cast<vtkContourRepresentation*>(this->WidgetRep)->
       AddNodeAtDisplayPosition( X, Y ) )
    {
    this->WidgetState = vtkContourWidget::Define;
    reinterpret_cast<vtkContourRepresentation*>(this->WidgetRep)->VisibilityOn();
    this->EventCallbackCommand->SetAbortFlag(1);
    }
}

//-------------------------------------------------------------------------
void vtkContourWidget::DeleteAction(vtkAbstractWidget *w)
{
  vtkContourWidget *self = reinterpret_cast<vtkContourWidget*>(w);

  if ( self->WidgetState == vtkContourWidget::Start )
    {
    return;
    }

  vtkContourRepresentation *rep =
    reinterpret_cast<vtkContourRepresentation*>(self->WidgetRep);

  if ( self->WidgetState == vtkContourWidget::Define )
    {
    rep->DeleteLastNode();
    }
  else
    {
    int X = self->Interactor->GetEventPosition()[0];
    int Y = self->Interactor->GetEventPosition()[1];
    rep->ActivateNode( X, Y );
    rep->DeleteActiveNode();
    rep->ActivateNode( X, Y );
    if ( rep->GetNumberOfNodes() < 3 )
      {
      rep->ClosedLoopOff();
      self->WidgetState = vtkContourWidget::Define;
      }
    }

  if ( rep->GetNeedToRender() )
    {
    self->Render();
    rep->NeedToRenderOff();
    }
}

//-------------------------------------------------------------------------
void vtkContourWidget::MoveAction(vtkAbstractWidget *w)
{
  vtkContourWidget *self = reinterpret_cast<vtkContourWidget*>(w);

  if ( self->WidgetState == vtkContourWidget::Start ||
       self->WidgetState == vtkContourWidget::Define )
    {
    return;
    }

  int X = self->Interactor->GetEventPosition()[0];
  int Y = self->Interactor->GetEventPosition()[1];
  vtkContourRepresentation *rep =
    reinterpret_cast<vtkContourRepresentation*>(self->WidgetRep);

  if ( rep->GetCurrentOperation() == vtkContourRepresentation::Inactive )
    {
    reinterpret_cast<vtkContourRepresentation*>(self->WidgetRep)->
      ComputeInteractionState( X, Y );
    reinterpret_cast<vtkContourRepresentation*>(self->WidgetRep)->
      ActivateNode( X, Y );
    }
  else
    {
    double pos[2];
    pos[0] = X;
    pos[1] = Y;
    self->WidgetRep->WidgetInteraction(pos);
    }

  self->Interaction();

  if ( self->WidgetRep->GetNeedToRender() )
    {
    self->Render();
    self->WidgetRep->NeedToRenderOff();
    }
}

//-------------------------------------------------------------------------
void vtkContourWidget::EndSelectAction(vtkAbstractWidget *w)
{
  vtkContourWidget *self = reinterpret_cast<vtkContourWidget*>(w);
  vtkContourRepresentation *rep =
    reinterpret_cast<vtkContourRepresentation*>(self->WidgetRep);

  // Do nothing if inactive
  if ( rep->GetCurrentOperation() == vtkContourRepresentation::Inactive )
    {
    return;
    }

  rep->SetCurrentOperationToInactive();
  self->EventCallbackCommand->SetAbortFlag(1);
  self->EndInteraction();

  if ( self->WidgetRep->GetNeedToRender() )
    {
    self->Render();
    self->WidgetRep->NeedToRenderOff();
    }
}

// These are callbacks that are active when the user is manipulating the
// handles of the measure widget.
//----------------------------------------------------------------------
void vtkContourWidget::StartInteraction()
{
  this->Superclass::StartInteraction();
  this->InvokeEvent(vtkCommand::StartInteractionEvent,NULL);
}

//----------------------------------------------------------------------
void vtkContourWidget::Interaction()
{
  this->InvokeEvent(vtkCommand::InteractionEvent,NULL);
}

//----------------------------------------------------------------------
void vtkContourWidget::EndInteraction()
{
  this->Superclass::EndInteraction();
  this->InvokeEvent(vtkCommand::EndInteractionEvent,NULL);
}

//----------------------------------------------------------------------
void vtkContourWidget::PrintSelf(ostream& os, vtkIndent indent)
{
  //Superclass typedef defined in vtkTypeMacro() found in vtkSetGet.h
  this->Superclass::PrintSelf(os,indent);

}
<|endoftext|>


<commit_before>// This file is part of the dune-stuff project:
//   https://github.com/wwu-numerik/dune-stuff/
// Copyright holders: Rene Milk, Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_STUFF_PLAYGROUND_FUNCTIONS_ESV2007_HH
#define DUNE_STUFF_PLAYGROUND_FUNCTIONS_ESV2007_HH

#include <limits>

#include <boost/numeric/conversion/cast.hpp>

#if HAVE_EIGEN

# include <Eigen/Eigenvalues>

# include <dune/geometry/quadraturerules.hh>

# include <dune/stuff/functions/ESV2007.hh>
# include <dune/stuff/common/debug.hh>
# include <dune/stuff/common/ranges.hh>

namespace Dune {
namespace Stuff {
namespace Functions {

namespace ESV2007 {

template< class DiffusionFactorType, class DiffusionTensorType >
class Cutoff
  : public LocalizableFunctionInterface< typename DiffusionFactorType::EntityType
                                       , typename DiffusionFactorType::DomainFieldType, DiffusionFactorType::dimDomain
                                       , typename DiffusionFactorType::RangeFieldType, 1, 1 >
{
  static_assert(std::is_base_of< Tags::LocalizableFunction, DiffusionFactorType >::value,
                "DiffusionFactorType has to be tagged as a LocalizableFunction!");
  static_assert(std::is_base_of< Tags::LocalizableFunction, DiffusionTensorType >::value,
                "DiffusionTensorType has to be tagged as a LocalizableFunction!");
  typedef typename DiffusionFactorType::EntityType E_;
  typedef typename DiffusionFactorType::DomainFieldType D_;
  static const unsigned int d_ = DiffusionFactorType::dimDomain;
  typedef typename DiffusionFactorType::RangeFieldType R_;
  typedef LocalizableFunctionInterface< E_, D_, d_, R_, 1 >  BaseType;
  typedef Cutoff< DiffusionFactorType, DiffusionTensorType > ThisType;

  static_assert(DiffusionFactorType::dimRange == 1, "The diffusion factor has to be scalar!");
  static_assert(DiffusionFactorType::dimRangeCols == 1, "The diffusion factor has to be scalar!");

  static_assert(std::is_same< typename DiffusionTensorType::EntityType, E_ >::value, "Types do not match!");
  static_assert(std::is_same< typename DiffusionTensorType::DomainFieldType, D_ >::value, "Types do not match!");
  static_assert(DiffusionTensorType::dimDomain == d_, "Dimensions do not match!");
  static_assert(std::is_same< typename DiffusionTensorType::RangeFieldType, R_ >::value, "Types do not match!");

  static_assert(DiffusionTensorType::dimRange == d_, "The diffusion tensor has to be a matrix!");
  static_assert(DiffusionTensorType::dimRangeCols == d_, "The diffusion tensor has to be a matrix!");

  class Localfunction
    : public LocalfunctionInterface< E_, D_, d_, R_, 1, 1 >
  {
    typedef LocalfunctionInterface< E_, D_, d_, R_, 1, 1 > BaseType;
  public:
    typedef typename BaseType::EntityType EntityType;

    typedef typename BaseType::DomainFieldType  DomainFieldType;
    static const unsigned int                   dimDomain = BaseType::dimDomain;
    typedef typename BaseType::DomainType       DomainType;

    typedef typename BaseType::RangeFieldType RangeFieldType;
    static const unsigned int                 dimRange = BaseType::dimRange;
    static const unsigned int                 dimRangeCols = BaseType::dimRangeCols;
    typedef typename BaseType::RangeType      RangeType;

    typedef typename BaseType::JacobianRangeType JacobianRangeType;

  private:
    template< class DF, int r, int rR >
    struct ComputeDiffusionFactor
    {
      static_assert(AlwaysFalse< DF >::value, "Not implemented for these dimensions!");
    };

    template< class DF >
    struct ComputeDiffusionFactor< DF, 1, 1 >
    {
      /**
       * We try to find the minimum of a polynomial of given order by evaluating it at the points of a quadrature that
       * would integrate this polynomial exactly.
       * \todo These are just some heuristics and should be replaced by something proper.
       */
      static RangeFieldType min_of(const DF& diffusion_factor, const EntityType& ent)
      {
        typename DF::RangeType tmp_value(0);
        RangeFieldType minimum = std::numeric_limits< RangeFieldType >::max();
        const auto local_diffusion_factor = diffusion_factor.local_function(ent);
        const size_t ord = local_diffusion_factor->order();
        assert(ord < std::numeric_limits< int >::max());
        const auto& quadrature = QuadratureRules< DomainFieldType, dimDomain >::rule(ent.type(), int(ord));
        const auto quad_point_it_end = quadrature.end();
        for (auto quad_point_it = quadrature.begin(); quad_point_it != quad_point_it_end; ++quad_point_it) {
          local_diffusion_factor->evaluate(quad_point_it->position(), tmp_value);
          minimum = std::min(minimum, tmp_value[0]);
        }
        return minimum;
      } // ... min_of(...)
    }; // class ComputeDiffusionFactor< ..., 1, 1 >

    template< class DT, int r, int rR >
    struct ComputeDiffusionTensor
    {
      static_assert(AlwaysFalse< DT >::value, "Not implemented for these dimensions!");
    };

    template< class DT, int d >
    struct ComputeDiffusionTensor< DT, d, d >
    {
      static RangeFieldType min_eigenvalue_of(const DT& diffusion_tensor, const EntityType& ent)
      {
#if !HAVE_EIGEN
        static_assert(AlwaysFalse< DT >::value, "You are missing eigen!");
#endif
        const auto local_diffusion_tensor = diffusion_tensor.local_function(ent);
        assert(local_diffusion_tensor->order() == 0);
        const auto& reference_element = ReferenceElements< DomainFieldType, dimDomain >::general(ent.type());
        const Stuff::LA::EigenDenseMatrix< RangeFieldType >
            tensor = local_diffusion_tensor->evaluate(reference_element.position(0, 0));
        ::Eigen::EigenSolver< typename Stuff::LA::EigenDenseMatrix< RangeFieldType >::BackendType >
            eigen_solver(tensor.backend());
        assert(eigen_solver.info() == ::Eigen::Success);
        const auto eigenvalues = eigen_solver.eigenvalues(); // <- this should be an Eigen vector of std::complex
        RangeFieldType min_ev = std::numeric_limits< RangeFieldType >::max();
        for (size_t ii = 0; ii < boost::numeric_cast< size_t >(eigenvalues.size()); ++ii) {
          // assert this is real
          assert(std::abs(eigenvalues[ii].imag()) < 1e-15);
          // assert that this eigenvalue is positive
          const RangeFieldType eigenvalue = eigenvalues[ii].real();
          assert(eigenvalue > 1e-15);
          min_ev = std::min(min_ev, eigenvalue);
        }
        return min_ev;
      } // ... min_eigenvalue_of_(...)
    }; // class Compute< ..., d, d >

  public:
    Localfunction(const EntityType& ent,
                  const DiffusionFactorType& diffusion_factor,
                  const DiffusionTensorType& diffusion_tensor,
                  const RangeFieldType poincare_constant)
      : BaseType(ent)
      , value_(0)
    {
      const RangeFieldType min_diffusion_factor
          = ComputeDiffusionFactor< DiffusionFactorType,
                                    DiffusionFactorType::dimRange,
                                    DiffusionFactorType::dimRangeCols >::min_of(diffusion_factor, ent);
      const RangeFieldType min_eigen_value_diffusion_tensor
          = ComputeDiffusionTensor< DiffusionTensorType,
                                    DiffusionTensorType::dimRange,
                                    DiffusionTensorType::dimRangeCols >::min_eigenvalue_of(diffusion_tensor, ent);
      assert(min_diffusion_factor > RangeFieldType(0));
      assert(min_eigen_value_diffusion_tensor > RangeFieldType(0));
      const DomainFieldType hh = compute_diameter_of_(ent);
      value_ = (poincare_constant * hh * hh) / (min_diffusion_factor * min_eigen_value_diffusion_tensor);
    } // Localfunction(...)

    Localfunction(const Localfunction& /*other*/) = delete;

    Localfunction& operator=(const Localfunction& /*other*/) = delete;

    virtual size_t order() const override final
    {
      return 0;
    }

    virtual void evaluate(const DomainType& UNUSED_UNLESS_DEBUG(xx), RangeType& ret) const override final
    {
      assert(this->is_a_valid_point(xx));
      ret[0] = value_;
    }

    virtual void jacobian(const DomainType& UNUSED_UNLESS_DEBUG(xx), JacobianRangeType& ret) const override final
    {
      assert(this->is_a_valid_point(xx));
      ret *= RangeFieldType(0);
    }

  private:
    static DomainFieldType compute_diameter_of_(const EntityType& ent)
    {
      DomainFieldType ret(0);
      for (auto cc : DSC::valueRange(ent.template count< dimDomain >())) {
        const auto vertex = ent.template subEntity< dimDomain >(cc)->geometry().center();
        for (auto dd : DSC::valueRange(cc + 1, ent.template count< dimDomain >())) {
          const auto other_vertex = ent.template subEntity< dimDomain >(dd)->geometry().center();
          const auto diff = vertex - other_vertex;
          ret = std::max(ret, diff.two_norm());
        }
      }
      return ret;
    } // ... compute_diameter_of_(...)

    RangeFieldType value_;
  }; // class Localfunction

public:
  typedef typename BaseType::EntityType         EntityType;
  typedef typename BaseType::LocalfunctionType  LocalfunctionType;

  typedef typename BaseType::DomainFieldType  DomainFieldType;
  static const unsigned int                   dimDomain = BaseType::dimDomain;
  typedef typename BaseType::DomainType       DomainType;

  typedef typename BaseType::RangeFieldType RangeFieldType;
  static const unsigned int                 dimRange = BaseType::dimRange;
  static const unsigned int                 dimRangeCols = BaseType::dimRangeCols;
  typedef typename BaseType::RangeType      RangeType;

  static std::string static_id()
  {
    return BaseType::static_id() + ".ESV2007.cutoff";
  }

  Cutoff(const DiffusionFactorType& diffusion_factor,
         const DiffusionTensorType& diffusion_tensor,
         const RangeFieldType poincare_constant = 1.0 / (M_PIl * M_PIl),
         const std::string nm = static_id())
    : diffusion_factor_(diffusion_factor)
    , diffusion_tensor_(diffusion_tensor)
    , poincare_constant_(poincare_constant)
    , name_(nm)
  {}

  Cutoff(const ThisType& other) = default;

  ThisType& operator=(const ThisType& other) = delete;

  virtual ThisType* copy() const override final
  {
    return new ThisType(*this);
  }

  virtual std::string name() const override final
  {
    return name_;
  }

  virtual std::unique_ptr< LocalfunctionType > local_function(const EntityType& entity) const override final
  {
    return std::unique_ptr< Localfunction >(new Localfunction(entity,
                                                              diffusion_factor_,
                                                              diffusion_tensor_,
                                                              poincare_constant_));
  }

private:
  const DiffusionFactorType& diffusion_factor_;
  const DiffusionTensorType& diffusion_tensor_;
  const RangeFieldType poincare_constant_;
  std::string name_;
}; // class Cutoff

} // namespace ESV2007
} // namespace Functions
} // namespace Stuff
} // namespace Dune

#endif // HAVE_EIGEN

#endif // DUNE_STUFF_PLAYGROUND_FUNCTIONS_ESV2007_HH
<commit_msg>[functions.ESV2007] refs #10<commit_after>// This file is part of the dune-stuff project:
//   https://github.com/wwu-numerik/dune-stuff/
// Copyright holders: Rene Milk, Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_STUFF_PLAYGROUND_FUNCTIONS_ESV2007_HH
#define DUNE_STUFF_PLAYGROUND_FUNCTIONS_ESV2007_HH

#include <limits>

#include <boost/numeric/conversion/cast.hpp>

#if HAVE_EIGEN

# include <Eigen/Eigenvalues>

# include <dune/geometry/quadraturerules.hh>

# include <dune/stuff/functions/ESV2007.hh>
# include <dune/stuff/common/debug.hh>
# include <dune/stuff/common/ranges.hh>

namespace Dune {
namespace Stuff {
namespace Functions {

namespace ESV2007 {

template< class DiffusionFactorType, class DiffusionTensorType >
class Cutoff
  : public LocalizableFunctionInterface< typename DiffusionFactorType::EntityType
                                       , typename DiffusionFactorType::DomainFieldType, DiffusionFactorType::dimDomain
                                       , typename DiffusionFactorType::RangeFieldType, 1, 1 >
{
  static_assert(std::is_base_of< Tags::LocalizableFunction, DiffusionFactorType >::value,
                "DiffusionFactorType has to be tagged as a LocalizableFunction!");
  static_assert(std::is_base_of< Tags::LocalizableFunction, DiffusionTensorType >::value,
                "DiffusionTensorType has to be tagged as a LocalizableFunction!");
  typedef typename DiffusionFactorType::EntityType E_;
  typedef typename DiffusionFactorType::DomainFieldType D_;
  static const unsigned int d_ = DiffusionFactorType::dimDomain;
  typedef typename DiffusionFactorType::RangeFieldType R_;
  typedef LocalizableFunctionInterface< E_, D_, d_, R_, 1 >  BaseType;
  typedef Cutoff< DiffusionFactorType, DiffusionTensorType > ThisType;

  static_assert(DiffusionFactorType::dimRange == 1, "The diffusion factor has to be scalar!");
  static_assert(DiffusionFactorType::dimRangeCols == 1, "The diffusion factor has to be scalar!");

  static_assert(std::is_same< typename DiffusionTensorType::EntityType, E_ >::value, "Types do not match!");
  static_assert(std::is_same< typename DiffusionTensorType::DomainFieldType, D_ >::value, "Types do not match!");
  static_assert(DiffusionTensorType::dimDomain == d_, "Dimensions do not match!");
  static_assert(std::is_same< typename DiffusionTensorType::RangeFieldType, R_ >::value, "Types do not match!");

  static_assert(DiffusionTensorType::dimRange == d_, "The diffusion tensor has to be a matrix!");
  static_assert(DiffusionTensorType::dimRangeCols == d_, "The diffusion tensor has to be a matrix!");

  class Localfunction
    : public LocalfunctionInterface< E_, D_, d_, R_, 1, 1 >
  {
    typedef LocalfunctionInterface< E_, D_, d_, R_, 1, 1 > BaseType;
  public:
    typedef typename BaseType::EntityType EntityType;

    typedef typename BaseType::DomainFieldType  DomainFieldType;
    static const unsigned int                   dimDomain = BaseType::dimDomain;
    typedef typename BaseType::DomainType       DomainType;

    typedef typename BaseType::RangeFieldType RangeFieldType;
    static const unsigned int                 dimRange = BaseType::dimRange;
    static const unsigned int                 dimRangeCols = BaseType::dimRangeCols;
    typedef typename BaseType::RangeType      RangeType;

    typedef typename BaseType::JacobianRangeType JacobianRangeType;

  private:
    template< class DF, int r, int rR >
    struct ComputeDiffusionFactor
    {
      static_assert(AlwaysFalse< DF >::value, "Not implemented for these dimensions!");
    };

    template< class DF >
    struct ComputeDiffusionFactor< DF, 1, 1 >
    {
      /**
       * We try to find the minimum of a polynomial of given order by evaluating it at the points of a quadrature that
       * would integrate this polynomial exactly.
       * \todo These are just some heuristics and should be replaced by something proper.
       */
      static RangeFieldType min_of(const DF& diffusion_factor, const EntityType& ent)
      {
        typename DF::RangeType tmp_value(0);
        RangeFieldType minimum = std::numeric_limits< RangeFieldType >::max();
        const auto local_diffusion_factor = diffusion_factor.local_function(ent);
        const size_t ord = local_diffusion_factor->order();
        const auto& quadrature = QuadratureRules< DomainFieldType, dimDomain >::rule(ent.type(),
                                                                                boost::numeric_cast< int >(ord));
        const auto quad_point_it_end = quadrature.end();
        for (auto quad_point_it = quadrature.begin(); quad_point_it != quad_point_it_end; ++quad_point_it) {
          local_diffusion_factor->evaluate(quad_point_it->position(), tmp_value);
          minimum = std::min(minimum, tmp_value[0]);
        }
        return minimum;
      } // ... min_of(...)
    }; // class ComputeDiffusionFactor< ..., 1, 1 >

    template< class DT, int r, int rR >
    struct ComputeDiffusionTensor
    {
      static_assert(AlwaysFalse< DT >::value, "Not implemented for these dimensions!");
    };

    template< class DT, int d >
    struct ComputeDiffusionTensor< DT, d, d >
    {
      static RangeFieldType min_eigenvalue_of(const DT& diffusion_tensor, const EntityType& ent)
      {
#if !HAVE_EIGEN
        static_assert(AlwaysFalse< DT >::value, "You are missing eigen!");
#endif
        const auto local_diffusion_tensor = diffusion_tensor.local_function(ent);
        assert(local_diffusion_tensor->order() == 0);
        const auto& reference_element = ReferenceElements< DomainFieldType, dimDomain >::general(ent.type());
        const Stuff::LA::EigenDenseMatrix< RangeFieldType >
            tensor = local_diffusion_tensor->evaluate(reference_element.position(0, 0));
        ::Eigen::EigenSolver< typename Stuff::LA::EigenDenseMatrix< RangeFieldType >::BackendType >
            eigen_solver(tensor.backend());
        assert(eigen_solver.info() == ::Eigen::Success);
        const auto eigenvalues = eigen_solver.eigenvalues(); // <- this should be an Eigen vector of std::complex
        RangeFieldType min_ev = std::numeric_limits< RangeFieldType >::max();
        for (size_t ii = 0; ii < boost::numeric_cast< size_t >(eigenvalues.size()); ++ii) {
          // assert this is real
          assert(std::abs(eigenvalues[ii].imag()) < 1e-15);
          // assert that this eigenvalue is positive
          const RangeFieldType eigenvalue = eigenvalues[ii].real();
          assert(eigenvalue > 1e-15);
          min_ev = std::min(min_ev, eigenvalue);
        }
        return min_ev;
      } // ... min_eigenvalue_of_(...)
    }; // class Compute< ..., d, d >

  public:
    Localfunction(const EntityType& ent,
                  const DiffusionFactorType& diffusion_factor,
                  const DiffusionTensorType& diffusion_tensor,
                  const RangeFieldType poincare_constant)
      : BaseType(ent)
      , value_(0)
    {
      const RangeFieldType min_diffusion_factor
          = ComputeDiffusionFactor< DiffusionFactorType,
                                    DiffusionFactorType::dimRange,
                                    DiffusionFactorType::dimRangeCols >::min_of(diffusion_factor, ent);
      const RangeFieldType min_eigen_value_diffusion_tensor
          = ComputeDiffusionTensor< DiffusionTensorType,
                                    DiffusionTensorType::dimRange,
                                    DiffusionTensorType::dimRangeCols >::min_eigenvalue_of(diffusion_tensor, ent);
      assert(min_diffusion_factor > RangeFieldType(0));
      assert(min_eigen_value_diffusion_tensor > RangeFieldType(0));
      const DomainFieldType hh = compute_diameter_of_(ent);
      value_ = (poincare_constant * hh * hh) / (min_diffusion_factor * min_eigen_value_diffusion_tensor);
    } // Localfunction(...)

    Localfunction(const Localfunction& /*other*/) = delete;

    Localfunction& operator=(const Localfunction& /*other*/) = delete;

    virtual size_t order() const override final
    {
      return 0;
    }

    virtual void evaluate(const DomainType& UNUSED_UNLESS_DEBUG(xx), RangeType& ret) const override final
    {
      assert(this->is_a_valid_point(xx));
      ret[0] = value_;
    }

    virtual void jacobian(const DomainType& UNUSED_UNLESS_DEBUG(xx), JacobianRangeType& ret) const override final
    {
      assert(this->is_a_valid_point(xx));
      ret *= RangeFieldType(0);
    }

  private:
    static DomainFieldType compute_diameter_of_(const EntityType& ent)
    {
      DomainFieldType ret(0);
      for (auto cc : DSC::valueRange(ent.template count< dimDomain >())) {
        const auto vertex = ent.template subEntity< dimDomain >(cc)->geometry().center();
        for (auto dd : DSC::valueRange(cc + 1, ent.template count< dimDomain >())) {
          const auto other_vertex = ent.template subEntity< dimDomain >(dd)->geometry().center();
          const auto diff = vertex - other_vertex;
          ret = std::max(ret, diff.two_norm());
        }
      }
      return ret;
    } // ... compute_diameter_of_(...)

    RangeFieldType value_;
  }; // class Localfunction

public:
  typedef typename BaseType::EntityType         EntityType;
  typedef typename BaseType::LocalfunctionType  LocalfunctionType;

  typedef typename BaseType::DomainFieldType  DomainFieldType;
  static const unsigned int                   dimDomain = BaseType::dimDomain;
  typedef typename BaseType::DomainType       DomainType;

  typedef typename BaseType::RangeFieldType RangeFieldType;
  static const unsigned int                 dimRange = BaseType::dimRange;
  static const unsigned int                 dimRangeCols = BaseType::dimRangeCols;
  typedef typename BaseType::RangeType      RangeType;

  static std::string static_id()
  {
    return BaseType::static_id() + ".ESV2007.cutoff";
  }

  Cutoff(const DiffusionFactorType& diffusion_factor,
         const DiffusionTensorType& diffusion_tensor,
         const RangeFieldType poincare_constant = 1.0 / (M_PIl * M_PIl),
         const std::string nm = static_id())
    : diffusion_factor_(diffusion_factor)
    , diffusion_tensor_(diffusion_tensor)
    , poincare_constant_(poincare_constant)
    , name_(nm)
  {}

  Cutoff(const ThisType& other) = default;

  ThisType& operator=(const ThisType& other) = delete;

  virtual ThisType* copy() const override final
  {
    return new ThisType(*this);
  }

  virtual std::string name() const override final
  {
    return name_;
  }

  virtual std::unique_ptr< LocalfunctionType > local_function(const EntityType& entity) const override final
  {
    return std::unique_ptr< Localfunction >(new Localfunction(entity,
                                                              diffusion_factor_,
                                                              diffusion_tensor_,
                                                              poincare_constant_));
  }

private:
  const DiffusionFactorType& diffusion_factor_;
  const DiffusionTensorType& diffusion_tensor_;
  const RangeFieldType poincare_constant_;
  std::string name_;
}; // class Cutoff

} // namespace ESV2007
} // namespace Functions
} // namespace Stuff
} // namespace Dune

#endif // HAVE_EIGEN

#endif // DUNE_STUFF_PLAYGROUND_FUNCTIONS_ESV2007_HH
<|endoftext|>


<commit_before>//
//  XLCObjCppHelpers.hh
//  XLCUtils
//
//  Created by Xiliang Chen on 14-4-27.
//  Copyright (c) 2014年 Xiliang Chen. All rights reserved.
//

#ifndef XLCUtils_XLCObjCppHelpers_hh
#define XLCUtils_XLCObjCppHelpers_hh

#include <type_traits>
#include <ostream>
#include <utility>
#include <string>
#include <typeinfo>

#include <cxxabi.h>

#ifndef __has_builtin           // Optional of course.
#define __has_builtin(x) 0      // Compatibility with non-clang compilers.
#endif
#ifndef __has_feature           // Optional of course.
#define __has_feature(x) 0      // Compatibility with non-clang compilers.
#endif
#ifndef __has_extension
#define __has_extension __has_feature // Compatibility with pre-3.0 compilers.
#endif

namespace xlc {

    template <bool T, class U = void>
    using enable_if_t = typename std::enable_if<T, U>::type;

    // callable_traits

    namespace detail {
        template <class ReturnType, class... Args>
        struct callable_traits_base
        {
            using return_type = ReturnType;
            using argument_type = std::tuple<Args...>;

            template<std::size_t I>
            using arg = typename std::tuple_element<I, argument_type>::type;
        };
    }

    template <class T>
    struct callable_traits : callable_traits<decltype(&T::operator())>
    {};

    // lambda / functor
    template <class ClassType, class ReturnType, class... Args>
    struct callable_traits<ReturnType(ClassType::*)(Args...) const>
    : detail::callable_traits_base<ReturnType, Args...>
    {};

    // function pointer
    template <class ReturnType, class... Args>
    struct callable_traits<ReturnType(Args...)>
    : detail::callable_traits_base<ReturnType, Args...>
    {};

    template <class ReturnType, class... Args>
    struct callable_traits<ReturnType(*)(Args...)>
    : detail::callable_traits_base<ReturnType, Args...>
    {};

#if __has_extension(blocks)
    // block
    template <class ReturnType, class... Args>
    struct callable_traits<ReturnType(^)(Args...)>
    : detail::callable_traits_base<ReturnType, Args...>
    {};
#endif

    // is_pair

    template <class T>
    struct is_pair : std::false_type {};

    template <class T1, class T2>
    struct is_pair<std::pair<T1, T2>> : std::true_type {};

    // is_for_loopable

    namespace detail {
        namespace is_for_loopable {
            using std::begin;   // enable ADL

            template<class T, class V = void>
            struct is_for_loopable : std::false_type { };

            template<class T>
            struct is_for_loopable<T,
            typename xlc::enable_if_t<!std::is_void<decltype(begin(std::declval<T>()))>::value>
            > : std::true_type { };

            template<class T, std::size_t N>
            struct is_for_loopable<T[N]> : std::true_type { };
        }
    }

    using detail::is_for_loopable::is_for_loopable;

    // is_objc_class

    template<class T, class V = void>
    struct is_objc_class : std::false_type { };

#ifdef __OBJC__
    template<class T>
    struct is_objc_class<T,
    typename std::enable_if<std::is_convertible<T, id>::value>::type
    > : std::true_type { };
#endif

    // type_description

    template <class T>
    std::string type_description() {
        bool is_lvalue_reference = std::is_lvalue_reference<T>::value;
        bool is_rvalue_reference = std::is_rvalue_reference<T>::value;
        bool is_const = std::is_const<typename std::remove_reference<T>::type>::value;

        std::unique_ptr<char, void(*)(void*)>
        name {abi::__cxa_demangle(typeid(T).name(), nullptr, nullptr, nullptr), std::free};

        auto str = std::string(name.get());
        if (is_const) {
            str += " const";
        }
        if (is_lvalue_reference) {
            str += "&";
        }
        if (is_rvalue_reference) {
            str += "&&";
        }

        return str;
    };
}

#ifdef __OBJC__
template <
class T,
class = typename xlc::enable_if_t<xlc::is_objc_class<T>::value>
>
std::ostream& operator<< (std::ostream& stream, T const & t) {
    stream << [[t description] UTF8String];
    return stream;
}
#endif

#endif
<commit_msg>some minor fixes<commit_after>//
//  XLCObjCppHelpers.hh
//  XLCUtils
//
//  Created by Xiliang Chen on 14-4-27.
//  Copyright (c) 2014年 Xiliang Chen. All rights reserved.
//

#ifndef XLCUtils_XLCObjCppHelpers_hh
#define XLCUtils_XLCObjCppHelpers_hh

#include <type_traits>
#include <ostream>
#include <utility>
#include <string>
#include <typeinfo>
#include <memory>

#include <cxxabi.h>

#ifndef __has_builtin           // Optional of course.
#define __has_builtin(x) 0      // Compatibility with non-clang compilers.
#endif
#ifndef __has_feature           // Optional of course.
#define __has_feature(x) 0      // Compatibility with non-clang compilers.
#endif
#ifndef __has_extension
#define __has_extension __has_feature // Compatibility with pre-3.0 compilers.
#endif

namespace xlc {

    template <bool T, class U = void>
    using enable_if_t = typename std::enable_if<T, U>::type;

    // callable_traits

    namespace detail {
        template <class ReturnType, class... Args>
        struct callable_traits_base
        {
            using return_type = ReturnType;
            using argument_type = std::tuple<Args...>;

            template<std::size_t I>
            using arg = typename std::tuple_element<I, argument_type>::type;
        };
    }

    template <class T>
    struct callable_traits : callable_traits<decltype(&T::operator())>
    {};

    // lambda / functor
    template <class ClassType, class ReturnType, class... Args>
    struct callable_traits<ReturnType(ClassType::*)(Args...) const>
    : detail::callable_traits_base<ReturnType, Args...>
    {};

    // function pointer
    template <class ReturnType, class... Args>
    struct callable_traits<ReturnType(Args...)>
    : detail::callable_traits_base<ReturnType, Args...>
    {};

    template <class ReturnType, class... Args>
    struct callable_traits<ReturnType(*)(Args...)>
    : detail::callable_traits_base<ReturnType, Args...>
    {};

#if __has_extension(blocks)
    // block
    template <class ReturnType, class... Args>
    struct callable_traits<ReturnType(^)(Args...)>
    : detail::callable_traits_base<ReturnType, Args...>
    {};
#endif

    // is_pair

    template <class T>
    struct is_pair : std::false_type {};

    template <class T1, class T2>
    struct is_pair<std::pair<T1, T2>> : std::true_type {};

    // is_for_loopable

    namespace detail {
        namespace is_for_loopable {
            using std::begin;   // enable ADL

            template<class T, class V = void>
            struct is_for_loopable : std::false_type { };

            template<class T>
            struct is_for_loopable<T,
            typename xlc::enable_if_t<!std::is_void<decltype(begin(std::declval<T>()))>::value>
            > : std::true_type { };

            template<class T, std::size_t N>
            struct is_for_loopable<T[N]> : std::true_type { };
        }
    }

    using detail::is_for_loopable::is_for_loopable;

    // is_objc_class

    template<class T, class V = void>
    struct is_objc_class : std::false_type { };

#ifdef __OBJC__
    template<class T>
    struct is_objc_class<T,
    typename std::enable_if<std::is_convertible<T, id>::value>::type
    > : std::true_type { };
#endif

    // type_description

    template <class T>
    std::string type_description() {
        bool is_lvalue_reference = std::is_lvalue_reference<T>::value;
        bool is_rvalue_reference = std::is_rvalue_reference<T>::value;
        bool is_const = std::is_const<typename std::remove_reference<T>::type>::value;

        std::unique_ptr<char, void(*)(void*)>
        name {abi::__cxa_demangle(typeid(T).name(), nullptr, nullptr, nullptr), std::free};

        auto str = std::string(name.get());
        if (is_const) {
            str += " const";
        }
        if (is_lvalue_reference) {
            str += "&";
        }
        if (is_rvalue_reference) {
            str += "&&";
        }

        return str;
    }
}

#ifdef __OBJC__
template <
class T,
class = typename xlc::enable_if_t<xlc::is_objc_class<T>::value>
>
std::ostream& operator<< (std::ostream& stream, T const & t) {
    stream << [[t description] UTF8String];
    return stream;
}
#endif

#endif
<|endoftext|>


<commit_before>/**
 * The Seeks proxy and plugin framework are part of the SEEKS project.
 * Copyright (C) 2010 Emmanuel Benazera, juban@free.fr
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "se_parser_yahoo_img.h"
#include "img_search_snippet.h"
#include "img_websearch_configuration.h"
#include "miscutil.h"
#include "encode.h"

#include <iostream>

using sp::miscutil;
using sp::encode;

namespace seeks_plugins
{

   se_parser_yahoo_img::se_parser_yahoo_img()
     :se_parser(),_results_flag(false),_cite_flag(false)
       {
       }

   se_parser_yahoo_img::~se_parser_yahoo_img()
     {
     }

   void se_parser_yahoo_img::start_element(parser_context *pc,
					  const xmlChar *name,
					  const xmlChar **attributes)
     {
	const char *tag = (const char*)name;

	if (!_results_flag && strcasecmp(tag,"ul") == 0)
	  {
	     const char *a_id = se_parser::get_attribute((const char**)attributes,"id");
	     if (a_id && strcasecmp(a_id,"yschimg") == 0)
	       {
		  _results_flag = true;
	       }
	  }
	else if (_results_flag && strcasecmp(tag,"li") == 0)
	  {
	     // assert previous snippet if any.
	     if (pc->_current_snippet)
	       {
		  if (0/* pc->_current_snippet->_title.empty()  // consider the parsing did fail on the snippet.
		      ||  pc->_current_snippet->_url.empty()
		      || pc->_current_snippet->_cached.empty() */)
		    {
		       delete pc->_current_snippet;
		       pc->_current_snippet = NULL;
		       _count--;
		    }
		  else pc->_snippets->push_back(pc->_current_snippet);
	       }
	     img_search_snippet *sp = new img_search_snippet(_count+1);
	     _count++;
	     sp->_img_engine |= std::bitset<IMG_NSEs>(SE_YAHOO_IMG);
	     pc->_current_snippet = sp;
	  }
	else if (_results_flag && strcasecmp(tag,"a") == 0)
	  {
	     const char *a_href = se_parser::get_attribute((const char**)attributes,"href");
	     if (a_href)
	       {
		  std::string furl = a_href;
		  size_t pos = furl.find("imgurl=");
		  if (pos != std::string::npos && pos+7 < furl.size())
		    {
		       std::string imgurl = furl.substr(pos+7);
		       pos = imgurl.find("%26");
		       if (pos != std::string::npos)
			 {
			    imgurl = imgurl.substr(0,pos);
			    imgurl = "http://" + imgurl;
			    char *imgurl_str = encode::url_decode(imgurl.c_str());
			    pc->_current_snippet->set_url(imgurl_str);
			    free(imgurl_str);
			 }
		    }
	       }
	  }
	else if (_results_flag && strcasecmp(tag,"img") == 0)
	  {
	     const char *a_src = se_parser::get_attribute((const char**)attributes,"src");
	     if (a_src)
	       {
		  pc->_current_snippet->_cached = a_src;
	       }
	  }
	else if (_results_flag && strcasecmp(tag,"cite") == 0)
	  {
	     _cite_flag = true;
	  }
     }

   void se_parser_yahoo_img::characters(parser_context *pc,
				       const xmlChar *chars,
				       int length)
     {
	handle_characters(pc, chars, length);
     }

   void se_parser_yahoo_img::cdata(parser_context *pc,
				  const xmlChar *chars,
				  int length)
     {
	//handle_characters(pc, chars, length);
     }

   void se_parser_yahoo_img::handle_characters(parser_context *pc,
					      const xmlChar *chars,
					      int length)
     {
	if (_cite_flag)
	  {
	     std::string cite = std::string((char*)chars,length);
	     _title += cite;
	  }
     }

   void se_parser_yahoo_img::end_element(parser_context *pc,
					const xmlChar *name)
     {
	const char *tag = (const char*)name;

	if (!_results_flag)
	  return;

	if (_results_flag && strcasecmp(tag,"ul") == 0)
	  _results_flag = false;

	if (_results_flag && strcasecmp(tag,"cite") == 0)
	  {
	     _cite_flag = false;
	     pc->_current_snippet->_title = _title;
	     _title.clear();
	  }
     }

} /* end of namespace. */
<commit_msg>fix to yahoo parser<commit_after>/**
 * The Seeks proxy and plugin framework are part of the SEEKS project.
 * Copyright (C) 2010 Emmanuel Benazera, juban@free.fr
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "se_parser_yahoo_img.h"
#include "img_search_snippet.h"
#include "img_websearch_configuration.h"
#include "miscutil.h"
#include "encode.h"

#include <iostream>

using sp::miscutil;
using sp::encode;

namespace seeks_plugins
{

   se_parser_yahoo_img::se_parser_yahoo_img()
     :se_parser(),_results_flag(false),_cite_flag(false)
       {
       }

   se_parser_yahoo_img::~se_parser_yahoo_img()
     {
     }

   void se_parser_yahoo_img::start_element(parser_context *pc,
					  const xmlChar *name,
					  const xmlChar **attributes)
     {
	const char *tag = (const char*)name;

	if (!_results_flag && strcasecmp(tag,"ul") == 0)
	  {
	     const char *a_id = se_parser::get_attribute((const char**)attributes,"id");
	     if (a_id && strcasecmp(a_id,"yschimg") == 0)
	       {
		  _results_flag = true;
	       }
	  }
	else if (_results_flag && strcasecmp(tag,"li") == 0)
	  {
	     // assert previous snippet if any.
	     if (pc->_current_snippet)
	       {
		  if (0/* pc->_current_snippet->_title.empty()  // consider the parsing did fail on the snippet.
		      ||  pc->_current_snippet->_url.empty()
		      || pc->_current_snippet->_cached.empty() */)
		    {
		       delete pc->_current_snippet;
		       pc->_current_snippet = NULL;
		       _count--;
		    }
		  else pc->_snippets->push_back(pc->_current_snippet);
	       }
	     img_search_snippet *sp = new img_search_snippet(_count+1);
	     _count++;
	     sp->_img_engine |= std::bitset<IMG_NSEs>(SE_YAHOO_IMG);
	     pc->_current_snippet = sp;
	  }
	else if (_results_flag && strcasecmp(tag,"a") == 0)
	  {
	     const char *a_href = se_parser::get_attribute((const char**)attributes,"href");
	     if (a_href)
	       {
		  std::string furl = a_href;
		  size_t pos = furl.find("imgurl=");
		  if (pos != std::string::npos && pos+7 < furl.size())
		    {
		       std::string imgurl = furl.substr(pos+7);
		       char *imgurl_str = encode::url_decode(imgurl.c_str());
		       imgurl = imgurl_str;
		       free(imgurl_str);
		       pos = imgurl.find("&");
		       if (pos != std::string::npos)
			 {
			    imgurl = imgurl.substr(0,pos);
			    imgurl = "http://" + imgurl;
			    pc->_current_snippet->set_url(imgurl);
			 }
		    }
	       }
	  }
	else if (_results_flag && strcasecmp(tag,"img") == 0)
	  {
	     const char *a_src = se_parser::get_attribute((const char**)attributes,"src");
	     if (a_src)
	       {
		  pc->_current_snippet->_cached = a_src;
	       }
	  }
	else if (_results_flag && strcasecmp(tag,"cite") == 0)
	  {
	     _cite_flag = true;
	  }
     }

   void se_parser_yahoo_img::characters(parser_context *pc,
				       const xmlChar *chars,
				       int length)
     {
	handle_characters(pc, chars, length);
     }

   void se_parser_yahoo_img::cdata(parser_context *pc,
				  const xmlChar *chars,
				  int length)
     {
	//handle_characters(pc, chars, length);
     }

   void se_parser_yahoo_img::handle_characters(parser_context *pc,
					      const xmlChar *chars,
					      int length)
     {
	if (_cite_flag)
	  {
	     std::string cite = std::string((char*)chars,length);
	     _title += cite;
	  }
     }

   void se_parser_yahoo_img::end_element(parser_context *pc,
					const xmlChar *name)
     {
	const char *tag = (const char*)name;

	if (!_results_flag)
	  return;

	if (_results_flag && strcasecmp(tag,"ul") == 0)
	  _results_flag = false;

	if (_results_flag && strcasecmp(tag,"cite") == 0)
	  {
	     _cite_flag = false;
	     pc->_current_snippet->_title = _title;
	     _title.clear();
	  }
     }

} /* end of namespace. */
<|endoftext|>


<commit_before>//===---- tools/extra/ToolTemplate.cpp - Template for refactoring tool ----===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file implements an empty refactoring tool using the clang tooling.
//  The goal is to lower the "barrier to entry" for writing refactoring tools.
//
//  Usage:
//  tool-template <cmake-output-dir> <file1> <file2> ...
//
//  Where <cmake-output-dir> is a CMake build directory in which a file named
//  compile_commands.json exists (enable -DCMAKE_EXPORT_COMPILE_COMMANDS in
//  CMake to get this output).
//
//  <file1> ... specify the paths of files in the CMake source tree. This path
//  is looked up in the compile command database. If the path of a file is
//  absolute, it needs to point into CMake's source tree. If the path is
//  relative, the current working directory needs to be in the CMake source
//  tree and the file must be in a subdirectory of the current working
//  directory. "./" prefixes in the relative files will be automatically
//  removed, but the rest of a relative path must be a suffix of a path in
//  the compile command line database.
//
//  For example, to use tool-template on all files in a subtree of the
//  source tree, use:
//
//    /path/in/subtree $ find . -name '*.cpp'|
//        xargs tool-template /path/to/build
//
//===----------------------------------------------------------------------===//

#include "clang/AST/ASTImporter.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Tooling/CommonOptionsParser.h"
#include "clang/Frontend/ASTUnit.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "llvm/Support/Signals.h"

using namespace clang;
using namespace clang::tooling;
using namespace llvm;

// Set up the command line options
static cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage);
static cl::OptionCategory ToolTemplateCategory("odr-check options");

typedef std::unique_ptr<ASTUnit> ASTUnitPtr;

class TagDeclVisitor : public RecursiveASTVisitor<TagDeclVisitor>
{
public:
  TagDeclVisitor(ASTUnit& to, ASTUnit& from)
    : m_to(to)
    , m_from(from)
    , m_importer(to.getASTContext(), to.getFileManager(),
                 from.getASTContext(), from.getFileManager(),
                 false) {
  }

  void MergeASTs() {
    TraverseDecl(m_from.getASTContext().getTranslationUnitDecl());
  }

  bool VisitTagDecl(TagDecl* fromDecl) {
    m_importer.Import(fromDecl);

    return true;
  }

private:
  ASTUnit& m_to;
  ASTUnit& m_from;
  ASTImporter m_importer;
};

int main(int argc, const char **argv) {
  llvm::sys::PrintStackTraceOnErrorSignal();
  //CommonOptionsParser OptionsParser(argc, argv, ToolTemplateCategory);

  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
  TextDiagnosticPrinter DiagnosticPrinter(
      llvm::errs(), &*DiagOpts);
  IntrusiveRefCntPtr<DiagnosticsEngine> Diagnostics = new DiagnosticsEngine(
      IntrusiveRefCntPtr<clang::DiagnosticIDs>(new DiagnosticIDs()), &*DiagOpts,
      &DiagnosticPrinter, false);

  std::vector<ASTUnitPtr> units;

  bool shouldDumpAST = false;

  ++argv;
  while (*argv) {
    const std::string arg = *argv;
    ++argv;

    if ("--should_dump_ast" == arg) {
      shouldDumpAST = true;
      continue;
    }

    llvm::errs() << "processing file [" << arg << "]...\n";
    ASTUnitPtr unit = ASTUnit::LoadFromASTFile(arg, Diagnostics, FileSystemOptions());
    if (unit) {
      units.push_back(std::move(unit));
    }
  }

  if (units.empty()) {
    llvm::errs() << "not AST units found\n";
    return 0;
  }

  auto front = units.begin();
  auto next = front + 1;
  ASTUnit& to = **front;

  while (next != units.end()) {
    ASTUnit& from = **next;
    llvm::errs() << "merging AST [" << from.getASTFileName() << "] to [" << to.getASTFileName() << "]...\n";

    TagDeclVisitor visitor(to, from);
    visitor.MergeASTs();

    ++next;
  }

  if (shouldDumpAST) {
    llvm::errs() << "dumping final AST...\n";
    ASTContext& finalContext = to.getASTContext();

    finalContext.getTranslationUnitDecl()->dump(llvm::errs());
  }

  return 0;
}
<commit_msg>Fixed issue with incorrect diagnostic printing<commit_after>//===---- tools/extra/ToolTemplate.cpp - Template for refactoring tool ----===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file implements an empty refactoring tool using the clang tooling.
//  The goal is to lower the "barrier to entry" for writing refactoring tools.
//
//  Usage:
//  tool-template <cmake-output-dir> <file1> <file2> ...
//
//  Where <cmake-output-dir> is a CMake build directory in which a file named
//  compile_commands.json exists (enable -DCMAKE_EXPORT_COMPILE_COMMANDS in
//  CMake to get this output).
//
//  <file1> ... specify the paths of files in the CMake source tree. This path
//  is looked up in the compile command database. If the path of a file is
//  absolute, it needs to point into CMake's source tree. If the path is
//  relative, the current working directory needs to be in the CMake source
//  tree and the file must be in a subdirectory of the current working
//  directory. "./" prefixes in the relative files will be automatically
//  removed, but the rest of a relative path must be a suffix of a path in
//  the compile command line database.
//
//  For example, to use tool-template on all files in a subtree of the
//  source tree, use:
//
//    /path/in/subtree $ find . -name '*.cpp'|
//        xargs tool-template /path/to/build
//
//===----------------------------------------------------------------------===//

#include "clang/AST/ASTImporter.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Tooling/CommonOptionsParser.h"
#include "clang/Frontend/ASTUnit.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "llvm/Support/Signals.h"

using namespace clang;
using namespace clang::tooling;
using namespace llvm;

// Set up the command line options
static cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage);
static cl::OptionCategory ToolTemplateCategory("odr-check options");

typedef std::unique_ptr<ASTUnit> ASTUnitPtr;

class TagDeclVisitor : public RecursiveASTVisitor<TagDeclVisitor>
{
public:
  TagDeclVisitor(ASTUnit& to, ASTUnit& from)
    : m_to(to)
    , m_from(from)
    , m_importer(to.getASTContext(), to.getFileManager(),
                 from.getASTContext(), from.getFileManager(),
                 false) {
  }

  void MergeASTs() {
    TraverseDecl(m_from.getASTContext().getTranslationUnitDecl());
  }

  bool VisitTagDecl(TagDecl* fromDecl) {
    m_importer.Import(fromDecl);

    return true;
  }

private:
  ASTUnit& m_to;
  ASTUnit& m_from;
  ASTImporter m_importer;
};

int main(int argc, const char **argv) {
  llvm::sys::PrintStackTraceOnErrorSignal();
  //CommonOptionsParser OptionsParser(argc, argv, ToolTemplateCategory);

  std::vector<ASTUnitPtr> units;

  bool shouldDumpAST = false;

  ++argv;
  while (*argv) {
    const std::string arg = *argv;
    ++argv;

    if ("--should_dump_ast" == arg) {
      shouldDumpAST = true;
      continue;
    }

    IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
    std::unique_ptr<TextDiagnosticPrinter> DiagnosticPrinter = llvm::make_unique<TextDiagnosticPrinter>(
        llvm::errs(), &*DiagOpts);

    IntrusiveRefCntPtr<DiagnosticsEngine> Diagnostics = new DiagnosticsEngine(
        IntrusiveRefCntPtr<clang::DiagnosticIDs>(new DiagnosticIDs()), &*DiagOpts,
        DiagnosticPrinter.release());

    llvm::errs() << "processing file [" << arg << "]...\n";
    ASTUnitPtr unit = ASTUnit::LoadFromASTFile(arg, Diagnostics, FileSystemOptions());
    if (unit) {
      units.push_back(std::move(unit));
    }
  }

  if (units.empty()) {
    llvm::errs() << "not AST units found\n";
    return 0;
  }

  auto front = units.begin();
  auto next = front + 1;
  ASTUnit& to = **front;

  while (next != units.end()) {
    ASTUnit& from = **next;
    llvm::errs() << "merging AST [" << from.getASTFileName() << "] to [" << to.getASTFileName() << "]...\n";

    TagDeclVisitor visitor(to, from);
    visitor.MergeASTs();

    ++next;
  }

  if (shouldDumpAST) {
    llvm::errs() << "dumping final AST...\n";
    ASTContext& finalContext = to.getASTContext();

    finalContext.getTranslationUnitDecl()->dump(llvm::errs());
  }

  return 0;
}
<|endoftext|>