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

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkObject.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) 2000 National Library of Medicine
  All rights reserved.

  See COPYRIGHT.txt for copyright details.

=========================================================================*/
#include "itkObject.h"
#include "itkObjectFactory.h"

// Initialize static member that controls warning display
static bool itkObjectGlobalWarningDisplay = 1;

void
itkObject
::SetGlobalWarningDisplay(bool val)
{
  itkObjectGlobalWarningDisplay = val;
}

bool
itkObject
::GetGlobalWarningDisplay()
{
  return itkObjectGlobalWarningDisplay;
}

// avoid dll boundary problems
#ifdef _WIN32
void*
itkObject
::operator new(size_t nSize, const char *, int)
{
  void* p=malloc(nSize);
  return p;
}

void*
itkObject
::operator new(size_t nSize)
{
  void* p=malloc(nSize);
  return p;
}

void
itkObject
::operator delete( void *p )
{
  free(p);
}
#endif

itkObject::Pointer
itkObject
::New()
{
  itkObject *ret = itkObjectFactory<itkObject>::Create();
  if ( ret )
    {
    return ret;
    }
  return new itkObject;
}

// Create an object with Debug turned off and modified time initialized
// to zero.
itkObject
::itkObject()
{
  m_Debug = 0;
  this->Modified(); // Insures modified time > than any other time
  // initial reference count = 0 because smart pointer immediately increments it
  m_ReferenceCount = 0;
  m_DeleteMethod = NULL;
}

// Delete a itk object. This method should always be used to delete an object
// when the new operator was used to create it. Using the C++ delete method
// will not work with reference counting.
void
itkObject
::Delete()
{
  this->UnRegister();
}

itkObject
::~itkObject()
{
  itkDebugMacro(<< "Destructing!");

  // warn user if reference counting is on and the object is being referenced
  // by another object
  if ( m_ReferenceCount > 0)
    {
    itkErrorMacro(<< "Trying to delete object with non-zero reference count.");
    }
}

// This operator allows all subclasses of itkObject to be printed via <<.
// It in turn invokes the Print method, which in turn will invoke the
// PrintSelf method that all objects should define, if they have anything
// interesting to print out.
std::ostream&
operator<<(std::ostream& os, itkObject& o)
{
  o.Print(os);
  return os;
}

void
itkObject
::Print(std::ostream& os)
{
  itkIndent indent;

  this->PrintHeader(os,0);
  this->PrintSelf(os, indent.GetNextIndent());
  this->PrintTrailer(os,0);
}

void
itkObject
::PrintHeader(std::ostream& os, itkIndent indent)
{
  os << indent << this->GetClassName() << " (" << this << ")\n";
}

void
itkObject
::PrintTrailer(std::ostream& os, itkIndent indent)
{
  os << indent << std::endl;
}

void
itkObject
::SetDeleteMethod(void (*f)(void *))
{
  if (f != m_DeleteMethod)
    {
    m_DeleteMethod = f;
    this->Modified();
    }
}

// Chaining method to print an object's instance variables, as well as
// its superclasses.
void
itkObject
::PrintSelf(std::ostream& os, itkIndent indent)
{
  os << indent << "m_Debug: " << (m_Debug ? "On\n" : "Off\n");

  if ( m_DeleteMethod )
    {
    os << indent << "Delete Method defined" << std::endl;
    }
  else
    {
    os << indent <<"No Delete Method" << std::endl;
    }
  os << indent << "Modified Time: " << this->GetMTime() << std::endl;
  os << indent << "Reference Count: " << m_ReferenceCount << std::endl;
}

// Return the modification for this object.
unsigned long
itkObject
::GetMTime()
{
  return m_MTime.GetMTime();
}

// Turn debugging output on.
void
itkObject
::DebugOn()
{
  m_Debug = 1;
}

// Turn debugging output off.
void
itkObject
::DebugOff()
{
  m_Debug = 0;
}

// Get the value of the debug flag.
bool
itkObject
::GetDebug()
{
  return m_Debug;
}

// Set the value of the debug flag. A non-zero value turns debugging on.
void
itkObject
::SetDebug(bool debugFlag)
{
  m_Debug = debugFlag;
}

// This method is called when itkErrorMacro executes. It allows
// the debugger to break on error.
void
itkObject
::BreakOnError()
{
  ;
}

// Sets the reference count (use with care)
void
itkObject
::SetReferenceCount(int ref)
{
  m_ReferenceCount = ref;
  itkDebugMacro(<< "Reference Count set to " << m_ReferenceCount);
}

// Increase the reference count (mark as used by another object).
void
itkObject
::Register()
{
  m_ReferenceCount++;
  itkDebugMacro(<< "Registered, "
                << "ReferenceCount = " << m_ReferenceCount);

  if (m_ReferenceCount <= 0)
    {
    delete this;
    }
}

// Decrease the reference count (release by another object).
void
itkObject
::UnRegister()
{
  itkDebugMacro(<< this << "UnRegistered, "
  << "ReferenceCount = " << (m_ReferenceCount-1));

  if (--m_ReferenceCount <= 0)
    {
    // invoke the delete method
    if ( m_DeleteMethod )
      {
      (*m_DeleteMethod)(this);
      }
    delete this;
    }
}

void
itkObject
::Modified()
{
  m_MTime.Modified();
}

<commit_msg>Made itkObject::GetDebug() a "const" function.<commit_after>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkObject.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) 2000 National Library of Medicine
  All rights reserved.

  See COPYRIGHT.txt for copyright details.

=========================================================================*/
#include "itkObject.h"
#include "itkObjectFactory.h"

// Initialize static member that controls warning display
static bool itkObjectGlobalWarningDisplay = 1;

void
itkObject
::SetGlobalWarningDisplay(bool val)
{
  itkObjectGlobalWarningDisplay = val;
}

bool
itkObject
::GetGlobalWarningDisplay()
{
  return itkObjectGlobalWarningDisplay;
}

// avoid dll boundary problems
#ifdef _WIN32
void*
itkObject
::operator new(size_t nSize, const char *, int)
{
  void* p=malloc(nSize);
  return p;
}

void*
itkObject
::operator new(size_t nSize)
{
  void* p=malloc(nSize);
  return p;
}

void
itkObject
::operator delete( void *p )
{
  free(p);
}
#endif

itkObject::Pointer
itkObject
::New()
{
  itkObject *ret = itkObjectFactory<itkObject>::Create();
  if ( ret )
    {
    return ret;
    }
  return new itkObject;
}

// Create an object with Debug turned off and modified time initialized
// to zero.
itkObject
::itkObject()
{
  m_Debug = 0;
  this->Modified(); // Insures modified time > than any other time
  // initial reference count = 0 because smart pointer immediately increments it
  m_ReferenceCount = 0;
  m_DeleteMethod = NULL;
}

// Delete a itk object. This method should always be used to delete an object
// when the new operator was used to create it. Using the C++ delete method
// will not work with reference counting.
void
itkObject
::Delete()
{
  this->UnRegister();
}

itkObject
::~itkObject()
{
  itkDebugMacro(<< "Destructing!");

  // warn user if reference counting is on and the object is being referenced
  // by another object
  if ( m_ReferenceCount > 0)
    {
    itkErrorMacro(<< "Trying to delete object with non-zero reference count.");
    }
}

// This operator allows all subclasses of itkObject to be printed via <<.
// It in turn invokes the Print method, which in turn will invoke the
// PrintSelf method that all objects should define, if they have anything
// interesting to print out.
std::ostream&
operator<<(std::ostream& os, itkObject& o)
{
  o.Print(os);
  return os;
}

void
itkObject
::Print(std::ostream& os)
{
  itkIndent indent;

  this->PrintHeader(os,0);
  this->PrintSelf(os, indent.GetNextIndent());
  this->PrintTrailer(os,0);
}

void
itkObject
::PrintHeader(std::ostream& os, itkIndent indent)
{
  os << indent << this->GetClassName() << " (" << this << ")\n";
}

void
itkObject
::PrintTrailer(std::ostream& os, itkIndent indent)
{
  os << indent << std::endl;
}

void
itkObject
::SetDeleteMethod(void (*f)(void *))
{
  if (f != m_DeleteMethod)
    {
    m_DeleteMethod = f;
    this->Modified();
    }
}

// Chaining method to print an object's instance variables, as well as
// its superclasses.
void
itkObject
::PrintSelf(std::ostream& os, itkIndent indent)
{
  os << indent << "m_Debug: " << (m_Debug ? "On\n" : "Off\n");

  if ( m_DeleteMethod )
    {
    os << indent << "Delete Method defined" << std::endl;
    }
  else
    {
    os << indent <<"No Delete Method" << std::endl;
    }
  os << indent << "Modified Time: " << this->GetMTime() << std::endl;
  os << indent << "Reference Count: " << m_ReferenceCount << std::endl;
}

// Return the modification for this object.
unsigned long
itkObject
::GetMTime()
{
  return m_MTime.GetMTime();
}

// Turn debugging output on.
void
itkObject
::DebugOn()
{
  m_Debug = 1;
}

// Turn debugging output off.
void
itkObject
::DebugOff()
{
  m_Debug = 0;
}

// Get the value of the debug flag.
bool
itkObject
::GetDebug() const
{
  return m_Debug;
}

// Set the value of the debug flag. A non-zero value turns debugging on.
void
itkObject
::SetDebug(bool debugFlag)
{
  m_Debug = debugFlag;
}

// This method is called when itkErrorMacro executes. It allows
// the debugger to break on error.
void
itkObject
::BreakOnError()
{
  ;
}

// Sets the reference count (use with care)
void
itkObject
::SetReferenceCount(int ref)
{
  m_ReferenceCount = ref;
  itkDebugMacro(<< "Reference Count set to " << m_ReferenceCount);
}

// Increase the reference count (mark as used by another object).
void
itkObject
::Register()
{
  m_ReferenceCount++;
  itkDebugMacro(<< "Registered, "
                << "ReferenceCount = " << m_ReferenceCount);

  if (m_ReferenceCount <= 0)
    {
    delete this;
    }
}

// Decrease the reference count (release by another object).
void
itkObject
::UnRegister()
{
  itkDebugMacro(<< this << "UnRegistered, "
  << "ReferenceCount = " << (m_ReferenceCount-1));

  if (--m_ReferenceCount <= 0)
    {
    // invoke the delete method
    if ( m_DeleteMethod )
      {
      (*m_DeleteMethod)(this);
      }
    delete this;
    }
}

void
itkObject
::Modified()
{
  m_MTime.Modified();
}

<|endoftext|>


<commit_before>//===--- CGComplexExpr.cpp - Emit LLVM Code for Complex Exprs -------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by Chris Lattner and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This contains code to emit Expr nodes with complex types as LLVM code.
//
//===----------------------------------------------------------------------===//

#include "CodeGenFunction.h"
#include "CodeGenModule.h"
#include "clang/AST/AST.h"
#include "llvm/Constants.h"
#include "llvm/Function.h"
#include "llvm/Support/Compiler.h"
using namespace clang;
using namespace CodeGen;

//===----------------------------------------------------------------------===//
//                        Complex Expression Emitter
//===----------------------------------------------------------------------===//

typedef CodeGenFunction::ComplexPairTy ComplexPairTy;

namespace  {
class VISIBILITY_HIDDEN ComplexExprEmitter
  : public StmtVisitor<ComplexExprEmitter, ComplexPairTy> {
  CodeGenFunction &CGF;
  llvm::LLVMBuilder &Builder;
public:
  ComplexExprEmitter(CodeGenFunction &cgf) : CGF(cgf), Builder(CGF.Builder) {
  }

  //===--------------------------------------------------------------------===//
  //                               Utilities
  //===--------------------------------------------------------------------===//

  /// EmitLoadOfLValue - Given an expression with complex type that represents a
  /// value l-value, this method emits the address of the l-value, then loads
  /// and returns the result.
  ComplexPairTy EmitLoadOfLValue(const Expr *E) {
    LValue LV = CGF.EmitLValue(E);
    // FIXME: Volatile
    return EmitLoadOfComplex(LV.getAddress(), false);
  }

  /// EmitLoadOfComplex - Given a pointer to a complex value, emit code to load
  /// the real and imaginary pieces.
  ComplexPairTy EmitLoadOfComplex(llvm::Value *SrcPtr, bool isVolatile);

  /// EmitStoreOfComplex - Store the specified real/imag parts into the
  /// specified value pointer.
  void EmitStoreOfComplex(ComplexPairTy Val, llvm::Value *ResPtr, bool isVol);

  //===--------------------------------------------------------------------===//
  //                            Visitor Methods
  //===--------------------------------------------------------------------===//

  ComplexPairTy VisitStmt(Stmt *S) {
    S->dump();
    assert(0 && "Stmt can't have complex result type!");
    return ComplexPairTy();
  }
  ComplexPairTy VisitExpr(Expr *S);
  ComplexPairTy VisitParenExpr(ParenExpr *PE) { return Visit(PE->getSubExpr());}

  // l-values.
  ComplexPairTy VisitDeclRefExpr(Expr *E) { return EmitLoadOfLValue(E); }
  ComplexPairTy VisitArraySubscriptExpr(Expr *E) { return EmitLoadOfLValue(E); }
  ComplexPairTy VisitMemberExpr(Expr *E) { return EmitLoadOfLValue(E); }

  // FIXME: Call
  // FIXME: CompoundLiteralExpr
  // FIXME: ImplicitCastExpr
  // FIXME: CastExpr

  // Operators.
  ComplexPairTy VisitPrePostIncDec(const UnaryOperator *E,
                                   bool isInc, bool isPre);
  ComplexPairTy VisitUnaryPostDec(const UnaryOperator *E) {
    return VisitPrePostIncDec(E, false, false);
  }
  ComplexPairTy VisitUnaryPostInc(const UnaryOperator *E) {
    return VisitPrePostIncDec(E, true, false);
  }
  ComplexPairTy VisitUnaryPreDec(const UnaryOperator *E) {
    return VisitPrePostIncDec(E, false, true);
  }
  ComplexPairTy VisitUnaryPreInc(const UnaryOperator *E) {
    return VisitPrePostIncDec(E, true, true);
  }
  ComplexPairTy VisitUnaryDeref(const Expr *E) { return EmitLoadOfLValue(E); }
  ComplexPairTy VisitUnaryPlus     (const UnaryOperator *E) {
    return Visit(E->getSubExpr());
  }
  ComplexPairTy VisitUnaryMinus    (const UnaryOperator *E);
  ComplexPairTy VisitUnaryNot      (const UnaryOperator *E);
  // LNot,SizeOf,AlignOf,Real,Imag never return complex.
  ComplexPairTy VisitUnaryExtension(const UnaryOperator *E) {
    return Visit(E->getSubExpr());
  }

  ComplexPairTy VisitBinMul        (const BinaryOperator *E);
  ComplexPairTy VisitBinAdd        (const BinaryOperator *E);
  // FIXME: div/rem
  // GCC rejects and/or/xor for integer complex.
  // Logical and/or always return int, never complex.

  // No comparisons produce a complex result.
  ComplexPairTy VisitBinAssign     (const BinaryOperator *E);
  // FIXME: Compound assignment operators.
  ComplexPairTy VisitBinComma      (const BinaryOperator *E);

  ComplexPairTy VisitConditionalOperator(const ConditionalOperator *CO);
  //  case Expr::ChooseExprClass:
};
}  // end anonymous namespace.

//===----------------------------------------------------------------------===//
//                                Utilities
//===----------------------------------------------------------------------===//

/// EmitLoadOfComplex - Given an RValue reference for a complex, emit code to
/// load the real and imaginary pieces, returning them as Real/Imag.
ComplexPairTy ComplexExprEmitter::EmitLoadOfComplex(llvm::Value *SrcPtr,
                                                    bool isVolatile) {
  llvm::Constant *Zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0);
  llvm::Constant *One  = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1);
  // FIXME: It would be nice to make this "Ptr->getName()+realp"
  llvm::Value *RealPtr = Builder.CreateGEP(SrcPtr, Zero, Zero, "realp");
  llvm::Value *ImagPtr = Builder.CreateGEP(SrcPtr, Zero, One, "imagp");

  // FIXME: It would be nice to make this "Ptr->getName()+real"
  llvm::Value *Real = Builder.CreateLoad(RealPtr, isVolatile, "real");
  llvm::Value *Imag = Builder.CreateLoad(ImagPtr, isVolatile, "imag");
  return ComplexPairTy(Real, Imag);
}

/// EmitStoreOfComplex - Store the specified real/imag parts into the
/// specified value pointer.
void ComplexExprEmitter::EmitStoreOfComplex(ComplexPairTy Val, llvm::Value *Ptr,
                                            bool isVolatile) {
  llvm::Constant *Zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0);
  llvm::Constant *One  = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1);
  llvm::Value *RealPtr = Builder.CreateGEP(Ptr, Zero, Zero, "real");
  llvm::Value *ImagPtr = Builder.CreateGEP(Ptr, Zero, One, "imag");

  Builder.CreateStore(Val.first, RealPtr, isVolatile);
  Builder.CreateStore(Val.second, ImagPtr, isVolatile);
}

//===----------------------------------------------------------------------===//
//                            Visitor Methods
//===----------------------------------------------------------------------===//

ComplexPairTy ComplexExprEmitter::VisitExpr(Expr *E) {
  fprintf(stderr, "Unimplemented complex expr!\n");
  E->dump();
  const llvm::Type *EltTy =
    CGF.ConvertType(E->getType()->getAsComplexType()->getElementType());
  llvm::Value *U = llvm::UndefValue::get(EltTy);
  return ComplexPairTy(U, U);
}

ComplexPairTy ComplexExprEmitter::VisitPrePostIncDec(const UnaryOperator *E,
                                                     bool isInc, bool isPre) {
  LValue LV = CGF.EmitLValue(E->getSubExpr());
  // FIXME: Handle volatile!
  ComplexPairTy InVal = EmitLoadOfComplex(LV.getAddress(), false);

  int AmountVal = isInc ? 1 : -1;

  llvm::Value *NextVal;
  if (isa<llvm::IntegerType>(InVal.first->getType()))
    NextVal = llvm::ConstantInt::get(InVal.first->getType(), AmountVal);
  else
    NextVal = llvm::ConstantFP::get(InVal.first->getType(), AmountVal);

  // Add the inc/dec to the real part.
  NextVal = Builder.CreateAdd(InVal.first, NextVal, isInc ? "inc" : "dec");

  ComplexPairTy IncVal(NextVal, InVal.second);

  // Store the updated result through the lvalue.
  EmitStoreOfComplex(IncVal, LV.getAddress(), false);  /* FIXME: Volatile */

  // If this is a postinc, return the value read from memory, otherwise use the
  // updated value.
  return isPre ? IncVal : InVal;
}

ComplexPairTy ComplexExprEmitter::VisitUnaryMinus(const UnaryOperator *E) {
  ComplexPairTy Op = Visit(E->getSubExpr());
  llvm::Value *ResR = Builder.CreateNeg(Op.first,  "neg.r");
  llvm::Value *ResI = Builder.CreateNeg(Op.second, "neg.i");
  return ComplexPairTy(ResR, ResI);
}

ComplexPairTy ComplexExprEmitter::VisitUnaryNot(const UnaryOperator *E) {
  // ~(a+ib) = a + i*-b
  ComplexPairTy Op = Visit(E->getSubExpr());
  llvm::Value *ResI = Builder.CreateNeg(Op.second, "conj.i");
  return ComplexPairTy(Op.first, ResI);
}

ComplexPairTy ComplexExprEmitter::VisitBinAdd(const BinaryOperator *E) {
  ComplexPairTy LHS = Visit(E->getLHS());
  ComplexPairTy RHS = Visit(E->getRHS());

  llvm::Value *ResR = Builder.CreateAdd(LHS.first,  RHS.first,  "add.r");
  llvm::Value *ResI = Builder.CreateAdd(LHS.second, RHS.second, "add.i");

  return ComplexPairTy(ResR, ResI);
}

ComplexPairTy ComplexExprEmitter::VisitBinMul(const BinaryOperator *E) {
  ComplexPairTy LHS = Visit(E->getLHS());
  ComplexPairTy RHS = Visit(E->getRHS());

  llvm::Value *ResRl = Builder.CreateMul(LHS.first, RHS.first, "mul.rl");
  llvm::Value *ResRr = Builder.CreateMul(LHS.second, RHS.second, "mul.rr");
  llvm::Value *ResR  = Builder.CreateSub(ResRl, ResRr, "mul.r");

  llvm::Value *ResIl = Builder.CreateMul(LHS.second, RHS.first, "mul.il");
  llvm::Value *ResIr = Builder.CreateMul(LHS.first, RHS.second, "mul.ir");
  llvm::Value *ResI  = Builder.CreateAdd(ResIl, ResIr, "mul.i");

  return ComplexPairTy(ResR, ResI);
}

ComplexPairTy ComplexExprEmitter::VisitBinAssign(const BinaryOperator *E) {
  assert(E->getLHS()->getType().getCanonicalType() ==
         E->getRHS()->getType().getCanonicalType() && "Invalid assignment");
  // Emit the RHS.
  ComplexPairTy Val = Visit(E->getRHS());

  // Compute the address to store into.
  LValue LHS = CGF.EmitLValue(E->getLHS());

  // Store into it.
  // FIXME: Volatility!
  EmitStoreOfComplex(Val, LHS.getAddress(), false);
  return Val;
}

ComplexPairTy ComplexExprEmitter::VisitBinComma(const BinaryOperator *E) {
  CGF.EmitStmt(E->getLHS());
  return Visit(E->getRHS());
}

ComplexPairTy ComplexExprEmitter::
VisitConditionalOperator(const ConditionalOperator *E) {
  llvm::BasicBlock *LHSBlock = new llvm::BasicBlock("cond.?");
  llvm::BasicBlock *RHSBlock = new llvm::BasicBlock("cond.:");
  llvm::BasicBlock *ContBlock = new llvm::BasicBlock("cond.cont");

  llvm::Value *Cond = CGF.EvaluateExprAsBool(E->getCond());
  Builder.CreateCondBr(Cond, LHSBlock, RHSBlock);

  CGF.EmitBlock(LHSBlock);

  // Handle the GNU extension for missing LHS.
  assert(E->getLHS() && "Must have LHS for complex value");

  ComplexPairTy LHS = Visit(E->getLHS());
  Builder.CreateBr(ContBlock);
  LHSBlock = Builder.GetInsertBlock();

  CGF.EmitBlock(RHSBlock);

  ComplexPairTy RHS = Visit(E->getRHS());
  Builder.CreateBr(ContBlock);
  RHSBlock = Builder.GetInsertBlock();

  CGF.EmitBlock(ContBlock);

  // Create a PHI node for the real part.
  llvm::PHINode *RealPN = Builder.CreatePHI(LHS.first->getType(), "cond.r");
  RealPN->reserveOperandSpace(2);
  RealPN->addIncoming(LHS.first, LHSBlock);
  RealPN->addIncoming(RHS.first, RHSBlock);

  // Create a PHI node for the imaginary part.
  llvm::PHINode *ImagPN = Builder.CreatePHI(LHS.first->getType(), "cond.i");
  ImagPN->reserveOperandSpace(2);
  ImagPN->addIncoming(LHS.second, LHSBlock);
  ImagPN->addIncoming(RHS.second, RHSBlock);

  return ComplexPairTy(RealPN, ImagPN);
}

//===----------------------------------------------------------------------===//
//                         Entry Point into this File
//===----------------------------------------------------------------------===//

/// EmitComplexExpr - Emit the computation of the specified expression of
/// complex type, ignoring the result.
ComplexPairTy CodeGenFunction::EmitComplexExpr(const Expr *E) {
  assert(E && E->getType()->isComplexType() &&
         "Invalid complex expression to emit");

  return ComplexExprEmitter(*this).Visit(const_cast<Expr*>(E));
}

<commit_msg>add support for codegen of calls returning complex.<commit_after>//===--- CGComplexExpr.cpp - Emit LLVM Code for Complex Exprs -------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by Chris Lattner and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This contains code to emit Expr nodes with complex types as LLVM code.
//
//===----------------------------------------------------------------------===//

#include "CodeGenFunction.h"
#include "CodeGenModule.h"
#include "clang/AST/AST.h"
#include "llvm/Constants.h"
#include "llvm/Function.h"
#include "llvm/Support/Compiler.h"
using namespace clang;
using namespace CodeGen;

//===----------------------------------------------------------------------===//
//                        Complex Expression Emitter
//===----------------------------------------------------------------------===//

typedef CodeGenFunction::ComplexPairTy ComplexPairTy;

namespace  {
class VISIBILITY_HIDDEN ComplexExprEmitter
  : public StmtVisitor<ComplexExprEmitter, ComplexPairTy> {
  CodeGenFunction &CGF;
  llvm::LLVMBuilder &Builder;
public:
  ComplexExprEmitter(CodeGenFunction &cgf) : CGF(cgf), Builder(CGF.Builder) {
  }

  //===--------------------------------------------------------------------===//
  //                               Utilities
  //===--------------------------------------------------------------------===//

  /// EmitLoadOfLValue - Given an expression with complex type that represents a
  /// value l-value, this method emits the address of the l-value, then loads
  /// and returns the result.
  ComplexPairTy EmitLoadOfLValue(const Expr *E) {
    LValue LV = CGF.EmitLValue(E);
    // FIXME: Volatile
    return EmitLoadOfComplex(LV.getAddress(), false);
  }

  /// EmitLoadOfComplex - Given a pointer to a complex value, emit code to load
  /// the real and imaginary pieces.
  ComplexPairTy EmitLoadOfComplex(llvm::Value *SrcPtr, bool isVolatile);

  /// EmitStoreOfComplex - Store the specified real/imag parts into the
  /// specified value pointer.
  void EmitStoreOfComplex(ComplexPairTy Val, llvm::Value *ResPtr, bool isVol);

  //===--------------------------------------------------------------------===//
  //                            Visitor Methods
  //===--------------------------------------------------------------------===//

  ComplexPairTy VisitStmt(Stmt *S) {
    S->dump();
    assert(0 && "Stmt can't have complex result type!");
    return ComplexPairTy();
  }
  ComplexPairTy VisitExpr(Expr *S);
  ComplexPairTy VisitParenExpr(ParenExpr *PE) { return Visit(PE->getSubExpr());}

  // l-values.
  ComplexPairTy VisitDeclRefExpr(Expr *E) { return EmitLoadOfLValue(E); }
  ComplexPairTy VisitArraySubscriptExpr(Expr *E) { return EmitLoadOfLValue(E); }
  ComplexPairTy VisitMemberExpr(Expr *E) { return EmitLoadOfLValue(E); }

  // FIXME: CompoundLiteralExpr
  // FIXME: ImplicitCastExpr
  ComplexPairTy VisitCallExpr(const CallExpr *E);

  // Operators.
  ComplexPairTy VisitPrePostIncDec(const UnaryOperator *E,
                                   bool isInc, bool isPre);
  ComplexPairTy VisitUnaryPostDec(const UnaryOperator *E) {
    return VisitPrePostIncDec(E, false, false);
  }
  ComplexPairTy VisitUnaryPostInc(const UnaryOperator *E) {
    return VisitPrePostIncDec(E, true, false);
  }
  ComplexPairTy VisitUnaryPreDec(const UnaryOperator *E) {
    return VisitPrePostIncDec(E, false, true);
  }
  ComplexPairTy VisitUnaryPreInc(const UnaryOperator *E) {
    return VisitPrePostIncDec(E, true, true);
  }
  ComplexPairTy VisitUnaryDeref(const Expr *E) { return EmitLoadOfLValue(E); }
  ComplexPairTy VisitUnaryPlus     (const UnaryOperator *E) {
    return Visit(E->getSubExpr());
  }
  ComplexPairTy VisitUnaryMinus    (const UnaryOperator *E);
  ComplexPairTy VisitUnaryNot      (const UnaryOperator *E);
  // LNot,SizeOf,AlignOf,Real,Imag never return complex.
  ComplexPairTy VisitUnaryExtension(const UnaryOperator *E) {
    return Visit(E->getSubExpr());
  }

  ComplexPairTy VisitBinMul        (const BinaryOperator *E);
  ComplexPairTy VisitBinAdd        (const BinaryOperator *E);
  // FIXME: sub/div/rem
  // GCC rejects and/or/xor for integer complex.
  // Logical and/or always return int, never complex.

  // No comparisons produce a complex result.
  ComplexPairTy VisitBinAssign     (const BinaryOperator *E);
  // FIXME: Compound assignment operators.
  ComplexPairTy VisitBinComma      (const BinaryOperator *E);

  ComplexPairTy VisitConditionalOperator(const ConditionalOperator *CO);
  //  case Expr::ChooseExprClass:
};
}  // end anonymous namespace.

//===----------------------------------------------------------------------===//
//                                Utilities
//===----------------------------------------------------------------------===//

/// EmitLoadOfComplex - Given an RValue reference for a complex, emit code to
/// load the real and imaginary pieces, returning them as Real/Imag.
ComplexPairTy ComplexExprEmitter::EmitLoadOfComplex(llvm::Value *SrcPtr,
                                                    bool isVolatile) {
  llvm::Constant *Zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0);
  llvm::Constant *One  = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1);
  // FIXME: It would be nice to make this "Ptr->getName()+realp"
  llvm::Value *RealPtr = Builder.CreateGEP(SrcPtr, Zero, Zero, "realp");
  llvm::Value *ImagPtr = Builder.CreateGEP(SrcPtr, Zero, One, "imagp");

  // FIXME: It would be nice to make this "Ptr->getName()+real"
  llvm::Value *Real = Builder.CreateLoad(RealPtr, isVolatile, "real");
  llvm::Value *Imag = Builder.CreateLoad(ImagPtr, isVolatile, "imag");
  return ComplexPairTy(Real, Imag);
}

/// EmitStoreOfComplex - Store the specified real/imag parts into the
/// specified value pointer.
void ComplexExprEmitter::EmitStoreOfComplex(ComplexPairTy Val, llvm::Value *Ptr,
                                            bool isVolatile) {
  llvm::Constant *Zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0);
  llvm::Constant *One  = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1);
  llvm::Value *RealPtr = Builder.CreateGEP(Ptr, Zero, Zero, "real");
  llvm::Value *ImagPtr = Builder.CreateGEP(Ptr, Zero, One, "imag");

  Builder.CreateStore(Val.first, RealPtr, isVolatile);
  Builder.CreateStore(Val.second, ImagPtr, isVolatile);
}

//===----------------------------------------------------------------------===//
//                            Visitor Methods
//===----------------------------------------------------------------------===//

ComplexPairTy ComplexExprEmitter::VisitExpr(Expr *E) {
  fprintf(stderr, "Unimplemented complex expr!\n");
  E->dump();
  const llvm::Type *EltTy =
    CGF.ConvertType(E->getType()->getAsComplexType()->getElementType());
  llvm::Value *U = llvm::UndefValue::get(EltTy);
  return ComplexPairTy(U, U);
}

ComplexPairTy ComplexExprEmitter::VisitCallExpr(const CallExpr *E) {
  llvm::Value *AggPtr = CGF.EmitCallExpr(E).getAggregateAddr();
  return EmitLoadOfComplex(AggPtr, false);
}

ComplexPairTy ComplexExprEmitter::VisitPrePostIncDec(const UnaryOperator *E,
                                                     bool isInc, bool isPre) {
  LValue LV = CGF.EmitLValue(E->getSubExpr());
  // FIXME: Handle volatile!
  ComplexPairTy InVal = EmitLoadOfComplex(LV.getAddress(), false);

  int AmountVal = isInc ? 1 : -1;

  llvm::Value *NextVal;
  if (isa<llvm::IntegerType>(InVal.first->getType()))
    NextVal = llvm::ConstantInt::get(InVal.first->getType(), AmountVal);
  else
    NextVal = llvm::ConstantFP::get(InVal.first->getType(), AmountVal);

  // Add the inc/dec to the real part.
  NextVal = Builder.CreateAdd(InVal.first, NextVal, isInc ? "inc" : "dec");

  ComplexPairTy IncVal(NextVal, InVal.second);

  // Store the updated result through the lvalue.
  EmitStoreOfComplex(IncVal, LV.getAddress(), false);  /* FIXME: Volatile */

  // If this is a postinc, return the value read from memory, otherwise use the
  // updated value.
  return isPre ? IncVal : InVal;
}

ComplexPairTy ComplexExprEmitter::VisitUnaryMinus(const UnaryOperator *E) {
  ComplexPairTy Op = Visit(E->getSubExpr());
  llvm::Value *ResR = Builder.CreateNeg(Op.first,  "neg.r");
  llvm::Value *ResI = Builder.CreateNeg(Op.second, "neg.i");
  return ComplexPairTy(ResR, ResI);
}

ComplexPairTy ComplexExprEmitter::VisitUnaryNot(const UnaryOperator *E) {
  // ~(a+ib) = a + i*-b
  ComplexPairTy Op = Visit(E->getSubExpr());
  llvm::Value *ResI = Builder.CreateNeg(Op.second, "conj.i");
  return ComplexPairTy(Op.first, ResI);
}

ComplexPairTy ComplexExprEmitter::VisitBinAdd(const BinaryOperator *E) {
  ComplexPairTy LHS = Visit(E->getLHS());
  ComplexPairTy RHS = Visit(E->getRHS());

  llvm::Value *ResR = Builder.CreateAdd(LHS.first,  RHS.first,  "add.r");
  llvm::Value *ResI = Builder.CreateAdd(LHS.second, RHS.second, "add.i");

  return ComplexPairTy(ResR, ResI);
}

ComplexPairTy ComplexExprEmitter::VisitBinMul(const BinaryOperator *E) {
  ComplexPairTy LHS = Visit(E->getLHS());
  ComplexPairTy RHS = Visit(E->getRHS());

  llvm::Value *ResRl = Builder.CreateMul(LHS.first, RHS.first, "mul.rl");
  llvm::Value *ResRr = Builder.CreateMul(LHS.second, RHS.second, "mul.rr");
  llvm::Value *ResR  = Builder.CreateSub(ResRl, ResRr, "mul.r");

  llvm::Value *ResIl = Builder.CreateMul(LHS.second, RHS.first, "mul.il");
  llvm::Value *ResIr = Builder.CreateMul(LHS.first, RHS.second, "mul.ir");
  llvm::Value *ResI  = Builder.CreateAdd(ResIl, ResIr, "mul.i");

  return ComplexPairTy(ResR, ResI);
}

ComplexPairTy ComplexExprEmitter::VisitBinAssign(const BinaryOperator *E) {
  assert(E->getLHS()->getType().getCanonicalType() ==
         E->getRHS()->getType().getCanonicalType() && "Invalid assignment");
  // Emit the RHS.
  ComplexPairTy Val = Visit(E->getRHS());

  // Compute the address to store into.
  LValue LHS = CGF.EmitLValue(E->getLHS());

  // Store into it.
  // FIXME: Volatility!
  EmitStoreOfComplex(Val, LHS.getAddress(), false);
  return Val;
}

ComplexPairTy ComplexExprEmitter::VisitBinComma(const BinaryOperator *E) {
  CGF.EmitStmt(E->getLHS());
  return Visit(E->getRHS());
}

ComplexPairTy ComplexExprEmitter::
VisitConditionalOperator(const ConditionalOperator *E) {
  llvm::BasicBlock *LHSBlock = new llvm::BasicBlock("cond.?");
  llvm::BasicBlock *RHSBlock = new llvm::BasicBlock("cond.:");
  llvm::BasicBlock *ContBlock = new llvm::BasicBlock("cond.cont");

  llvm::Value *Cond = CGF.EvaluateExprAsBool(E->getCond());
  Builder.CreateCondBr(Cond, LHSBlock, RHSBlock);

  CGF.EmitBlock(LHSBlock);

  // Handle the GNU extension for missing LHS.
  assert(E->getLHS() && "Must have LHS for complex value");

  ComplexPairTy LHS = Visit(E->getLHS());
  Builder.CreateBr(ContBlock);
  LHSBlock = Builder.GetInsertBlock();

  CGF.EmitBlock(RHSBlock);

  ComplexPairTy RHS = Visit(E->getRHS());
  Builder.CreateBr(ContBlock);
  RHSBlock = Builder.GetInsertBlock();

  CGF.EmitBlock(ContBlock);

  // Create a PHI node for the real part.
  llvm::PHINode *RealPN = Builder.CreatePHI(LHS.first->getType(), "cond.r");
  RealPN->reserveOperandSpace(2);
  RealPN->addIncoming(LHS.first, LHSBlock);
  RealPN->addIncoming(RHS.first, RHSBlock);

  // Create a PHI node for the imaginary part.
  llvm::PHINode *ImagPN = Builder.CreatePHI(LHS.first->getType(), "cond.i");
  ImagPN->reserveOperandSpace(2);
  ImagPN->addIncoming(LHS.second, LHSBlock);
  ImagPN->addIncoming(RHS.second, RHSBlock);

  return ComplexPairTy(RealPN, ImagPN);
}

//===----------------------------------------------------------------------===//
//                         Entry Point into this File
//===----------------------------------------------------------------------===//

/// EmitComplexExpr - Emit the computation of the specified expression of
/// complex type, ignoring the result.
ComplexPairTy CodeGenFunction::EmitComplexExpr(const Expr *E) {
  assert(E && E->getType()->isComplexType() &&
         "Invalid complex expression to emit");

  return ComplexExprEmitter(*this).Visit(const_cast<Expr*>(E));
}

<|endoftext|>


<commit_before>/*
                     Copyright (C) 1991,1995 by

                      MATRA DATAVISION, FRANCE

This software is furnished in accordance with the terms and conditions
of the contract and with the inclusion of the above copyright notice
This software or any other copy thereof may not be provided or otherwise
be made available to any other person. No title to an ownership of the
software is hereby transferred

At the termination of the contract, the software and all copies of this
software must be deleted

Facility : CAS-CADE V1.3A

*/

#ifndef _Standard_Macro_HeaderFile
#include <Standard_Macro.hxx>
#endif

#ifdef WNT

# ifndef __MATH_WNT_H
#  define __MATH_WNT_H

__Standard_API double __cdecl acosh ( double );
__Standard_API double __cdecl asinh ( double );
__Standard_API double __cdecl atanh ( double );

#if defined(M_PI_2)
# undef M_PI_2
#endif

# define M_SQRT1_2  7.0710678118654752440E-1
# define M_PI_2     1.57079632679489661923

# endif  /* __MATH_WNT_H */

#endif  /* WNT */

<commit_msg>fix a lot of redefinition warnings if M_SQRT1_2 is already defined<commit_after>/*
                     Copyright (C) 1991,1995 by

                      MATRA DATAVISION, FRANCE

This software is furnished in accordance with the terms and conditions
of the contract and with the inclusion of the above copyright notice
This software or any other copy thereof may not be provided or otherwise
be made available to any other person. No title to an ownership of the
software is hereby transferred

At the termination of the contract, the software and all copies of this
software must be deleted

Facility : CAS-CADE V1.3A

*/

#ifndef _Standard_Macro_HeaderFile
#include <Standard_Macro.hxx>
#endif

#ifdef WNT

# ifndef __MATH_WNT_H
#  define __MATH_WNT_H

__Standard_API double __cdecl acosh ( double );
__Standard_API double __cdecl asinh ( double );
__Standard_API double __cdecl atanh ( double );

#if defined(M_PI_2)
# undef M_PI_2
#endif
# define M_PI_2     1.57079632679489661923

#if defined(M_SQRT1_2)
# undef M_SQRT1_2
#endif
# define M_SQRT1_2  7.0710678118654752440E-1

# endif  /* __MATH_WNT_H */

#endif  /* WNT */

<|endoftext|>


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

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center (DKFZ)
All rights reserved.

Use of this source code is governed by a 3-clause BSD license that can be
found in the LICENSE file.

============================================================================*/

#include "mitkFillRegionBaseTool.h"
#include "mitkToolManager.h"

#include "mitkBaseRenderer.h"
#include "mitkDataStorage.h"

#include "mitkITKImageImport.h"
#include "mitkImageAccessByItk.h"

#include "mitkRenderingManager.h"

#include <itkConnectedThresholdImageFilter.h>

mitk::FillRegionBaseTool::FillRegionBaseTool() : SegTool2D("MouseReleaseOnly")
{
}

mitk::FillRegionBaseTool::~FillRegionBaseTool()
{
}

void mitk::FillRegionBaseTool::ConnectActionsAndFunctions()
{
  CONNECT_FUNCTION("Release", OnClick);
}

template <typename TPixel, unsigned int VImageDimension>
void DoITKRegionGrowing(const itk::Image<TPixel, VImageDimension>* oldSegImage,
  mitk::Image::Pointer& filledRegionImage, itk::Index<VImageDimension> seedIndex, mitk::Label::PixelType& seedLabel )
{
  typedef itk::Image<TPixel, VImageDimension> InputImageType;
  typedef itk::Image<mitk::Label::PixelType, VImageDimension> OutputImageType;
  typedef itk::ConnectedThresholdImageFilter<InputImageType, OutputImageType> RegionGrowingFilterType;

  seedLabel = oldSegImage->GetPixel(seedIndex);

  typename OutputImageType::Pointer itkResultImage;
  filledRegionImage = nullptr;

  try
  {
    typename RegionGrowingFilterType::Pointer regionGrower = RegionGrowingFilterType::New();
    regionGrower->SetInput(oldSegImage);
    regionGrower->SetReplaceValue(1);
    regionGrower->AddSeed(seedIndex);

    regionGrower->SetLower(seedLabel);
    regionGrower->SetUpper(seedLabel);

    regionGrower->Update();

    itkResultImage = regionGrower->GetOutput();
  }
  catch (const itk::ExceptionObject&)
  {
    return; // can't work
  }
  catch (...)
  {
    return;
  }
  mitk::CastToMitkImage(itkResultImage, filledRegionImage);
}

#include "mitkIOUtil.h"

void mitk::FillRegionBaseTool::OnClick(StateMachineAction*, InteractionEvent* interactionEvent)
{
  auto positionEvent = dynamic_cast<mitk::InteractionPositionEvent*>(interactionEvent);
  if (nullptr == positionEvent)
    return;

  auto labelSetImage = dynamic_cast<const LabelSetImage*>(this->GetWorkingData());
  if (nullptr == labelSetImage)
  {
    return;
  }

  if (!IsPositionEventInsideImageRegion(positionEvent, labelSetImage))
  {
    return;
  }

  m_LastEventSender = positionEvent->GetSender();
  m_LastEventSlice = m_LastEventSender->GetSlice();

  auto workingSlice = this->GetAffectedWorkingSlice(positionEvent);

  auto click = positionEvent->GetPositionInWorld();

  auto workingImage = this->GetWorkingData();

  auto fillImage = this->GenerateFillImage(workingSlice, click);
  this->PrepareFilling(workingSlice, click);

  TransferLabelContent(fillImage, workingSlice, labelSetImage->GetActiveLabelSet(), 0, labelSetImage->GetExteriorLabel()->GetValue(), false, { {1, m_FillValue} }, m_MergeStyle);

  this->WriteBackSegmentationResult(positionEvent, workingSlice);

  mitk::RenderingManager::GetInstance()->RequestUpdate(positionEvent->GetSender()->GetRenderWindow());
}

mitk::Image::Pointer mitk::FillRegionBaseTool::GenerateFillImage(const Image* workingSlice, Point3D seedPoint) const
{
  itk::Index<2> seedIndex;
  workingSlice->GetGeometry()->WorldToIndex(seedPoint, seedIndex);

  Image::Pointer fillImage;
  Label::PixelType seedLabelValue;

  AccessFixedDimensionByItk_n(workingSlice, DoITKRegionGrowing, 2, (fillImage, seedIndex, seedLabelValue));

  auto labelSetImage = dynamic_cast<const LabelSetImage*>(this->GetWorkingData());
  if (nullptr != labelSetImage)
  {
    auto label = labelSetImage->GetLabel(seedLabelValue, labelSetImage->GetActiveLayer());

    if (label->GetLocked())
    {
      ErrorMessage.Send("Label of selected region is locked. Tool operation may not have an effect.");
    }
  }

  return fillImage;
}

<commit_msg>fixed compile error<commit_after>/*============================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center (DKFZ)
All rights reserved.

Use of this source code is governed by a 3-clause BSD license that can be
found in the LICENSE file.

============================================================================*/

#include "mitkFillRegionBaseTool.h"
#include "mitkToolManager.h"

#include "mitkBaseRenderer.h"
#include "mitkDataStorage.h"

#include "mitkITKImageImport.h"
#include "mitkImageAccessByItk.h"

#include "mitkRenderingManager.h"

#include <itkConnectedThresholdImageFilter.h>

mitk::FillRegionBaseTool::FillRegionBaseTool() : SegTool2D("MouseReleaseOnly")
{
}

mitk::FillRegionBaseTool::~FillRegionBaseTool()
{
}

void mitk::FillRegionBaseTool::ConnectActionsAndFunctions()
{
  CONNECT_FUNCTION("Release", OnClick);
}

template <typename TPixel, unsigned int VImageDimension>
void DoITKRegionGrowing(const itk::Image<TPixel, VImageDimension>* oldSegImage,
  mitk::Image::Pointer& filledRegionImage, itk::Index<VImageDimension> seedIndex, mitk::Label::PixelType& seedLabel )
{
  typedef itk::Image<TPixel, VImageDimension> InputImageType;
  typedef itk::Image<mitk::Label::PixelType, VImageDimension> OutputImageType;
  typedef itk::ConnectedThresholdImageFilter<InputImageType, OutputImageType> RegionGrowingFilterType;

  seedLabel = oldSegImage->GetPixel(seedIndex);

  typename OutputImageType::Pointer itkResultImage;
  filledRegionImage = nullptr;

  try
  {
    typename RegionGrowingFilterType::Pointer regionGrower = RegionGrowingFilterType::New();
    regionGrower->SetInput(oldSegImage);
    regionGrower->SetReplaceValue(1);
    regionGrower->AddSeed(seedIndex);

    regionGrower->SetLower(seedLabel);
    regionGrower->SetUpper(seedLabel);

    regionGrower->Update();

    itkResultImage = regionGrower->GetOutput();
  }
  catch (const itk::ExceptionObject&)
  {
    return; // can't work
  }
  catch (...)
  {
    return;
  }
  mitk::CastToMitkImage(itkResultImage, filledRegionImage);
}

#include "mitkIOUtil.h"

void mitk::FillRegionBaseTool::OnClick(StateMachineAction*, InteractionEvent* interactionEvent)
{
  auto positionEvent = dynamic_cast<mitk::InteractionPositionEvent*>(interactionEvent);
  if (nullptr == positionEvent)
    return;

  auto labelSetImage = dynamic_cast<const LabelSetImage*>(this->GetWorkingData());
  if (nullptr == labelSetImage)
  {
    return;
  }

  if (!IsPositionEventInsideImageRegion(positionEvent, labelSetImage))
  {
    return;
  }

  m_LastEventSender = positionEvent->GetSender();
  m_LastEventSlice = m_LastEventSender->GetSlice();

  auto workingSlice = this->GetAffectedWorkingSlice(positionEvent);

  auto click = positionEvent->GetPositionInWorld();

  auto fillImage = this->GenerateFillImage(workingSlice, click);
  this->PrepareFilling(workingSlice, click);

  TransferLabelContent(fillImage, workingSlice, labelSetImage->GetActiveLabelSet(), 0, labelSetImage->GetExteriorLabel()->GetValue(), false, { {1, m_FillValue} }, m_MergeStyle);

  this->WriteBackSegmentationResult(positionEvent, workingSlice);

  mitk::RenderingManager::GetInstance()->RequestUpdate(positionEvent->GetSender()->GetRenderWindow());
}

mitk::Image::Pointer mitk::FillRegionBaseTool::GenerateFillImage(const Image* workingSlice, Point3D seedPoint) const
{
  itk::Index<2> seedIndex;
  workingSlice->GetGeometry()->WorldToIndex(seedPoint, seedIndex);

  Image::Pointer fillImage;
  Label::PixelType seedLabelValue;

  AccessFixedDimensionByItk_n(workingSlice, DoITKRegionGrowing, 2, (fillImage, seedIndex, seedLabelValue));

  auto labelSetImage = dynamic_cast<const LabelSetImage*>(this->GetWorkingData());
  if (nullptr != labelSetImage)
  {
    auto label = labelSetImage->GetLabel(seedLabelValue, labelSetImage->GetActiveLayer());

    if (label->GetLocked())
    {
      ErrorMessage.Send("Label of selected region is locked. Tool operation may not have an effect.");
    }
  }

  return fillImage;
}

<|endoftext|>


<commit_before>/* This file is part of the KDE libraries
   Copyright (C) 2003 Hamish Rodda <rodda@kde.org>

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public
   License version 2 as published by the Free Software Foundation.

   This library 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
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public License
   along with this library; see the file COPYING.LIB.  If not, write to
   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
   Boston, MA 02110-1301, USA.
*/

#include "katesmartcursor.h"

#include "katedocument.h"
#include "katesmartmanager.h"
#include "katesmartcursornotifier.h"

#include <kdebug.h>

KateSmartCursor::KateSmartCursor(const KTextEditor::Cursor& position, KTextEditor::Document* doc, bool moveOnInsert)
  : KTextEditor::SmartCursor(position, doc, moveOnInsert)
  , m_feedbackEnabled(false)
  , m_oldGroupLineStart(-1)
  , m_lastPosition(position)
  , m_notifier(0L)
  , m_watcher(0L)
{
  if (position > kateDocument()->documentEnd()) {
    kdWarning() << k_funcinfo << "Attempted to set cursor position past end of document." << endl;
    m_line = -1;
  }

  // Replace straight line number with smartgroup + line offset
  m_smartGroup = kateDocument()->smartManager()->groupForLine(m_line);
  m_line = m_line - m_smartGroup->startLine();
  m_smartGroup->joined(this);
}

KateSmartCursor::KateSmartCursor( KTextEditor::Document * doc, bool moveOnInsert )
  : KTextEditor::SmartCursor(KTextEditor::Cursor(), doc, moveOnInsert)
  , m_feedbackEnabled(false)
  , m_oldGroupLineStart(-1)
  , m_notifier(0L)
  , m_watcher(0L)
{
  // Replace straight line number with smartgroup + line offset
  m_smartGroup = kateDocument()->smartManager()->groupForLine(m_line);
  m_line = m_line - m_smartGroup->startLine();
  m_smartGroup->joined(this);
}

KateSmartCursor::~KateSmartCursor()
{
  m_smartGroup->leaving(this);
  if (m_notifier)
    delete m_notifier;
}

KateSmartCursor::operator QString()
{
  return QString("[%1,%1]").arg(line()).arg(column());
}

KateDocument* KateSmartCursor::kateDocument() const
{
  return static_cast<KateDocument*>(document());
}

bool KateSmartCursor::isValid( ) const
{
  return line() >= 0 && line() <= kateDocument()->lastLine() && column() >= 0 && column() <= kateDocument()->lineLength(line());
}

bool KateSmartCursor::isValid(const Cursor& position) const
{
  return position.line() >= 0 && position.line() <= kateDocument()->lastLine() && position.column() >= 0 && position.column() <= kateDocument()->lineLength(position.line());
}

bool KateSmartCursor::atEndOfLine( ) const
{
  return line() >= 0 && line() <= kateDocument()->lastLine() && column() >= kateDocument()->lineLength(line());
}

void KateSmartCursor::checkFeedback()
{
  bool feedbackNeeded = m_watcher || m_notifier;
  if (m_feedbackEnabled != feedbackNeeded) {
    m_smartGroup->changeCursorFeedback(this);
    m_feedbackEnabled = feedbackNeeded;
  }
}

int KateSmartCursor::line( ) const
{
  return m_smartGroup->startLine() + m_line;
}

void KateSmartCursor::setLine( int _line )
{
  setPositionInternal(KTextEditor::Cursor(_line, m_column), false);
}

void KateSmartCursor::setPositionInternal( const KTextEditor::Cursor & pos, bool internal )
{
  // Shortcut if there's no change :)
  if (*this == pos)
    return;

  KTextEditor::Cursor old = *this;

  // Remember this position if the feedback system needs it
  if (m_feedbackEnabled)
    m_lastPosition = *this;

  // Deal with crossing a smart group border
  bool haveToChangeGroups = !m_smartGroup->containsLine(pos.line());
  if (haveToChangeGroups) {
    m_smartGroup->leaving(this);
    m_smartGroup = kateDocument()->smartManager()->groupForLine(pos.line());
  }

  // Set the new position
  m_line = pos.line() - m_smartGroup->newStartLine();
  m_column = pos.column();

  // Finish dealing with crossing a smart group border
  if (haveToChangeGroups) {
    m_smartGroup->joined(this);
  }

  // Forget this position change if the feedback system doesn't need it
  if (!m_feedbackEnabled)
    m_lastPosition = *this;

  // Adjustments only needed for non-internal position changes...
  if (!internal)
    // Tell the range about this
    cursorChangedDirectly(old);
}

KTextEditor::SmartCursorNotifier* KateSmartCursor::notifier( )
{
  if (!m_notifier) {
    m_notifier = new KateSmartCursorNotifier();
    checkFeedback();
  }
  return m_notifier;
}

void KateSmartCursor::deleteNotifier( )
{
  delete m_notifier;
  m_notifier = 0L;
  checkFeedback();
}

void KateSmartCursor::setWatcher( KTextEditor::SmartCursorWatcher * watcher )
{
  m_watcher = watcher;
  checkFeedback();
}

bool KateSmartCursor::translate( const KateEditInfo & edit )
{
  // If this cursor is before the edit, no action is required
  if (*this < edit.start())
    return false;

  // If this cursor is on a line affected by the edit
  if (edit.oldRange().overlapsLine(line())) {
    // If this cursor is at the start of the edit
    if (*this == edit.start()) {
      // And it doesn't need to move, no action is required
      if (!moveOnInsert())
        return false;
    }

    // Calculate the new position
    KTextEditor::Cursor newPos;
    if (edit.oldRange().contains(*this)) {
      if (moveOnInsert())
        newPos = edit.newRange().end();
      else
        newPos = edit.start();

    } else {
      newPos = *this + edit.translate();
    }

    if (newPos != *this) {
      setPositionInternal(newPos);
      return true;
    }

    return false;
  }

  // just need to adjust line number
  setLineInternal(line() + edit.translate().line());
  return true;
}

bool KateSmartCursor::cursorMoved( ) const
{
  bool ret = m_oldGroupLineStart != m_smartGroup->startLine();
  m_oldGroupLineStart = m_smartGroup->startLine();
  return ret;
}

void KateSmartCursor::setLineInternal( int newLine, bool internal )
{
  setPositionInternal(KTextEditor::Cursor(newLine, column()), internal);
}

void KateSmartCursor::translated(const KateEditInfo & edit)
{
  if (*this < edit.start()) {
    if (!range() || !static_cast<KateSmartRange*>(range())->feedbackEnabled())
      m_lastPosition = *this;
    return;
  }

  // We can rely on m_lastPosition because it is updated in translate(), otherwise just shifted() is called
  if (m_lastPosition != *this) {
    // position changed
    if (m_notifier)
      emit m_notifier->positionChanged(this);
    if (m_watcher)
      m_watcher->positionChanged(this);
  }

  if (!edit.oldRange().isEmpty() && edit.start() <= m_lastPosition && edit.oldRange().end() >= m_lastPosition) {
    if (edit.start() == m_lastPosition) {
      // character deleted after
      if (m_notifier)
        emit m_notifier->characterDeleted(this, false);
      if (m_watcher)
        m_watcher->characterDeleted(this, false);

    } else if (edit.oldRange().end() == m_lastPosition) {
      // character deleted before
      if (m_notifier)
        emit m_notifier->characterDeleted(this, true);
      if (m_watcher)
        m_watcher->characterDeleted(this, true);

    } else {
      // position deleted
      if (m_notifier)
        emit m_notifier->positionDeleted(this);
      if (m_watcher)
        m_watcher->positionDeleted(this);
    }
  }

  if (!edit.newRange().isEmpty()) {
    if (*this == edit.newRange().start()) {
      // character inserted after
      if (m_notifier)
        emit m_notifier->characterInserted(this, false);
      if (m_watcher)
        m_watcher->characterInserted(this, false);

    } else if (*this == edit.newRange().end()) {
      // character inserted before
      if (m_notifier)
        emit m_notifier->characterInserted(this, true);
      if (m_watcher)
        m_watcher->characterInserted(this, true);
    }
  }

  if (!range() || !static_cast<KateSmartRange*>(range())->feedbackEnabled())
    m_lastPosition = *this;
}

void KateSmartCursor::shifted( )
{
  Q_ASSERT(m_lastPosition != *this);

  // position changed
  if (m_notifier)
    emit m_notifier->positionChanged(this);
  if (m_watcher)
    m_watcher->positionChanged(this);

  if (!range() || !static_cast<KateSmartRange*>(range())->feedbackEnabled())
    m_lastPosition = *this;
}

void KateSmartCursor::migrate( KateSmartGroup * newGroup )
{
  int lineNum = line();
  m_smartGroup = newGroup;
  m_line = lineNum - m_smartGroup->startLine();
}

void KateSmartCursor::setPosition( const KTextEditor::Cursor & pos )
{
  if (pos > kateDocument()->documentEnd()) {
    kdWarning() << k_funcinfo << "Attempted to set cursor position past end of document." << endl;
    setPositionInternal(invalid(), false);
    return;
  }

  setPositionInternal(pos, false);
}

void KateSmartCursor::resetLastPosition( )
{
  m_lastPosition = *this;
}

bool KateSmartCursor::hasNotifier( ) const
{
  return m_notifier;
}

KTextEditor::SmartCursorWatcher * KateSmartCursor::watcher( ) const
{
  return m_watcher;
}

// kate: space-indent on; indent-width 2; replace-tabs on;
<commit_msg>More API review - mostly documentation changes: * separated members into documentation groups (looks nice) * noticed a few more inconsistencies by reading the generated   documentation - corrected * tried to use covariant return for Range:: start() and end(),   but gcc barfed on assignment to it :( * miscellaneous documentation cleanups<commit_after>/* This file is part of the KDE libraries
   Copyright (C) 2003 Hamish Rodda <rodda@kde.org>

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public
   License version 2 as published by the Free Software Foundation.

   This library 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
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public License
   along with this library; see the file COPYING.LIB.  If not, write to
   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
   Boston, MA 02110-1301, USA.
*/

#include "katesmartcursor.h"

#include "katedocument.h"
#include "katesmartmanager.h"
#include "katesmartcursornotifier.h"

#include <kdebug.h>

KateSmartCursor::KateSmartCursor(const KTextEditor::Cursor& position, KTextEditor::Document* doc, bool moveOnInsert)
  : KTextEditor::SmartCursor(position, doc, moveOnInsert)
  , m_feedbackEnabled(false)
  , m_oldGroupLineStart(-1)
  , m_lastPosition(position)
  , m_notifier(0L)
  , m_watcher(0L)
{
  if (position > kateDocument()->documentEnd()) {
    kdWarning() << k_funcinfo << "Attempted to set cursor position past end of document." << endl;
    m_line = -1;
  }

  // Replace straight line number with smartgroup + line offset
  m_smartGroup = kateDocument()->smartManager()->groupForLine(m_line);
  m_line = m_line - m_smartGroup->startLine();
  m_smartGroup->joined(this);
}

KateSmartCursor::KateSmartCursor( KTextEditor::Document * doc, bool moveOnInsert )
  : KTextEditor::SmartCursor(KTextEditor::Cursor(), doc, moveOnInsert)
  , m_feedbackEnabled(false)
  , m_oldGroupLineStart(-1)
  , m_notifier(0L)
  , m_watcher(0L)
{
  // Replace straight line number with smartgroup + line offset
  m_smartGroup = kateDocument()->smartManager()->groupForLine(m_line);
  m_line = m_line - m_smartGroup->startLine();
  m_smartGroup->joined(this);
}

KateSmartCursor::~KateSmartCursor()
{
  if (m_notifier) {
    emit m_notifier->deleted(this);
    delete m_notifier;
  }

  if (m_watcher)
    m_watcher->deleted(this);

  m_smartGroup->leaving(this);
}

KateSmartCursor::operator QString()
{
  return QString("[%1,%1]").arg(line()).arg(column());
}

KateDocument* KateSmartCursor::kateDocument() const
{
  return static_cast<KateDocument*>(document());
}

bool KateSmartCursor::isValid( ) const
{
  return line() >= 0 && line() <= kateDocument()->lastLine() && column() >= 0 && column() <= kateDocument()->lineLength(line());
}

bool KateSmartCursor::isValid(const Cursor& position) const
{
  return position.line() >= 0 && position.line() <= kateDocument()->lastLine() && position.column() >= 0 && position.column() <= kateDocument()->lineLength(position.line());
}

bool KateSmartCursor::atEndOfLine( ) const
{
  return line() >= 0 && line() <= kateDocument()->lastLine() && column() >= kateDocument()->lineLength(line());
}

void KateSmartCursor::checkFeedback()
{
  bool feedbackNeeded = m_watcher || m_notifier;
  if (m_feedbackEnabled != feedbackNeeded) {
    m_smartGroup->changeCursorFeedback(this);
    m_feedbackEnabled = feedbackNeeded;
  }
}

int KateSmartCursor::line( ) const
{
  return m_smartGroup->startLine() + m_line;
}

void KateSmartCursor::setLine( int _line )
{
  setPositionInternal(KTextEditor::Cursor(_line, m_column), false);
}

void KateSmartCursor::setPositionInternal( const KTextEditor::Cursor & pos, bool internal )
{
  // Shortcut if there's no change :)
  if (*this == pos)
    return;

  KTextEditor::Cursor old = *this;

  // Remember this position if the feedback system needs it
  if (m_feedbackEnabled)
    m_lastPosition = *this;

  // Deal with crossing a smart group border
  bool haveToChangeGroups = !m_smartGroup->containsLine(pos.line());
  if (haveToChangeGroups) {
    m_smartGroup->leaving(this);
    m_smartGroup = kateDocument()->smartManager()->groupForLine(pos.line());
  }

  // Set the new position
  m_line = pos.line() - m_smartGroup->newStartLine();
  m_column = pos.column();

  // Finish dealing with crossing a smart group border
  if (haveToChangeGroups) {
    m_smartGroup->joined(this);
  }

  // Forget this position change if the feedback system doesn't need it
  if (!m_feedbackEnabled)
    m_lastPosition = *this;

  // Adjustments only needed for non-internal position changes...
  if (!internal)
    // Tell the range about this
    cursorChangedDirectly(old);
}

KTextEditor::SmartCursorNotifier* KateSmartCursor::notifier( )
{
  if (!m_notifier) {
    m_notifier = new KateSmartCursorNotifier();
    checkFeedback();
  }
  return m_notifier;
}

void KateSmartCursor::deleteNotifier( )
{
  delete m_notifier;
  m_notifier = 0L;
  checkFeedback();
}

void KateSmartCursor::setWatcher( KTextEditor::SmartCursorWatcher * watcher )
{
  m_watcher = watcher;
  checkFeedback();
}

bool KateSmartCursor::translate( const KateEditInfo & edit )
{
  // If this cursor is before the edit, no action is required
  if (*this < edit.start())
    return false;

  // If this cursor is on a line affected by the edit
  if (edit.oldRange().overlapsLine(line())) {
    // If this cursor is at the start of the edit
    if (*this == edit.start()) {
      // And it doesn't need to move, no action is required
      if (!moveOnInsert())
        return false;
    }

    // Calculate the new position
    KTextEditor::Cursor newPos;
    if (edit.oldRange().contains(*this)) {
      if (moveOnInsert())
        newPos = edit.newRange().end();
      else
        newPos = edit.start();

    } else {
      newPos = *this + edit.translate();
    }

    if (newPos != *this) {
      setPositionInternal(newPos);
      return true;
    }

    return false;
  }

  // just need to adjust line number
  setLineInternal(line() + edit.translate().line());
  return true;
}

bool KateSmartCursor::cursorMoved( ) const
{
  bool ret = m_oldGroupLineStart != m_smartGroup->startLine();
  m_oldGroupLineStart = m_smartGroup->startLine();
  return ret;
}

void KateSmartCursor::setLineInternal( int newLine, bool internal )
{
  setPositionInternal(KTextEditor::Cursor(newLine, column()), internal);
}

void KateSmartCursor::translated(const KateEditInfo & edit)
{
  if (*this < edit.start()) {
    if (!range() || !static_cast<KateSmartRange*>(range())->feedbackEnabled())
      m_lastPosition = *this;
    return;
  }

  // We can rely on m_lastPosition because it is updated in translate(), otherwise just shifted() is called
  if (m_lastPosition != *this) {
    // position changed
    if (m_notifier)
      emit m_notifier->positionChanged(this);
    if (m_watcher)
      m_watcher->positionChanged(this);
  }

  if (!edit.oldRange().isEmpty() && edit.start() <= m_lastPosition && edit.oldRange().end() >= m_lastPosition) {
    if (edit.start() == m_lastPosition) {
      // character deleted after
      if (m_notifier)
        emit m_notifier->characterDeleted(this, false);
      if (m_watcher)
        m_watcher->characterDeleted(this, false);

    } else if (edit.oldRange().end() == m_lastPosition) {
      // character deleted before
      if (m_notifier)
        emit m_notifier->characterDeleted(this, true);
      if (m_watcher)
        m_watcher->characterDeleted(this, true);

    } else {
      // position deleted
      if (m_notifier)
        emit m_notifier->positionDeleted(this);
      if (m_watcher)
        m_watcher->positionDeleted(this);
    }
  }

  if (!edit.newRange().isEmpty()) {
    if (*this == edit.newRange().start()) {
      // character inserted after
      if (m_notifier)
        emit m_notifier->characterInserted(this, false);
      if (m_watcher)
        m_watcher->characterInserted(this, false);

    } else if (*this == edit.newRange().end()) {
      // character inserted before
      if (m_notifier)
        emit m_notifier->characterInserted(this, true);
      if (m_watcher)
        m_watcher->characterInserted(this, true);
    }
  }

  if (!range() || !static_cast<KateSmartRange*>(range())->feedbackEnabled())
    m_lastPosition = *this;
}

void KateSmartCursor::shifted( )
{
  Q_ASSERT(m_lastPosition != *this);

  // position changed
  if (m_notifier)
    emit m_notifier->positionChanged(this);
  if (m_watcher)
    m_watcher->positionChanged(this);

  if (!range() || !static_cast<KateSmartRange*>(range())->feedbackEnabled())
    m_lastPosition = *this;
}

void KateSmartCursor::migrate( KateSmartGroup * newGroup )
{
  int lineNum = line();
  m_smartGroup = newGroup;
  m_line = lineNum - m_smartGroup->startLine();
}

void KateSmartCursor::setPosition( const KTextEditor::Cursor & pos )
{
  if (pos > kateDocument()->documentEnd()) {
    kdWarning() << k_funcinfo << "Attempted to set cursor position past end of document." << endl;
    setPositionInternal(invalid(), false);
    return;
  }

  setPositionInternal(pos, false);
}

void KateSmartCursor::resetLastPosition( )
{
  m_lastPosition = *this;
}

bool KateSmartCursor::hasNotifier( ) const
{
  return m_notifier;
}

KTextEditor::SmartCursorWatcher * KateSmartCursor::watcher( ) const
{
  return m_watcher;
}

// kate: space-indent on; indent-width 2; replace-tabs on;
<|endoftext|>


<commit_before>// ----------------------------------------------------------------------------
// PSP Player Emulation Suite
// Copyright (C) 2006 Ben Vanik (noxa)
// Licensed under the LGPL - see License.txt in the project root for details
// ----------------------------------------------------------------------------

#include "StdAfx.h"
#include "R4000Generator.h"
#include "R4000Cpu.h"
#include "R4000Core.h"
#include "R4000Memory.h"
#include "R4000GenContext.h"

#include "Loader.hpp"
#include "CodeGenerator.hpp"

using namespace System::Diagnostics;
using namespace Noxa::Emulation::Psp;
using namespace Noxa::Emulation::Psp::Cpu;
using namespace SoftWire;

#define g context->Generator

GenerationResult SYSCALL( R4000GenContext^ context, int pass, int address, uint code, byte opcode, byte rs, byte rt, byte rd, byte shamt, byte function )
{
	if( pass == 0 )
	{
	}
	else if( pass == 1 )
	{
	}
	return GenerationResult::Invalid;
}

GenerationResult BREAK( R4000GenContext^ context, int pass, int address, uint code, byte opcode, byte rs, byte rt, byte rd, byte shamt, byte function )
{
	if( pass == 0 )
	{
	}
	else if( pass == 1 )
	{
	}
	return GenerationResult::Invalid;
}

GenerationResult SYNC( R4000GenContext^ context, int pass, int address, uint code, byte opcode, byte rs, byte rt, byte rd, byte shamt, byte function )
{
	if( pass == 0 )
	{
	}
	else if( pass == 1 )
	{
	}
	return GenerationResult::Invalid;
}

GenerationResult COP1( R4000GenContext^ context, int pass, int address, uint code, byte opcode, byte rs, byte rt, ushort imm )
{
	if( pass == 0 )
	{
	}
	else if( pass == 1 )
	{
	}
	return GenerationResult::Invalid;
}

GenerationResult COP2( R4000GenContext^ context, int pass, int address, uint code, byte opcode, byte rs, byte rt, ushort imm )
{
	if( pass == 0 )
	{
	}
	else if( pass == 1 )
	{
	}
	return GenerationResult::Invalid;
}

GenerationResult HALT( R4000GenContext^ context, int pass, int address, uint code, byte opcode, byte rs, byte rt, byte rd, byte shamt, byte function )
{
	if( pass == 0 )
	{
	}
	else if( pass == 1 )
	{
	}
	return GenerationResult::Invalid;
}

GenerationResult MFIC( R4000GenContext^ context, int pass, int address, uint code, byte opcode, byte rs, byte rt, byte rd, byte shamt, byte function )
{
	if( pass == 0 )
	{
	}
	else if( pass == 1 )
	{
	}
	return GenerationResult::Invalid;
}

GenerationResult MTIC( R4000GenContext^ context, int pass, int address, uint code, byte opcode, byte rs, byte rt, byte rd, byte shamt, byte function )
{
	if( pass == 0 )
	{
	}
	else if( pass == 1 )
	{
	}
	return GenerationResult::Invalid;
}
<commit_msg>The code I had forgot to checkin - special instructions besides SYSCALL (needs to be converted).<commit_after>// ----------------------------------------------------------------------------
// PSP Player Emulation Suite
// Copyright (C) 2006 Ben Vanik (noxa)
// Licensed under the LGPL - see License.txt in the project root for details
// ----------------------------------------------------------------------------

#include "StdAfx.h"
#include "R4000Generator.h"
#include "R4000Cpu.h"
#include "R4000Core.h"
#include "R4000Memory.h"
#include "R4000GenContext.h"

#include "Loader.hpp"
#include "CodeGenerator.hpp"

using namespace System::Diagnostics;
using namespace Noxa::Emulation::Psp;
using namespace Noxa::Emulation::Psp::Bios;
using namespace Noxa::Emulation::Psp::Cpu;
using namespace SoftWire;

#define g context->Generator

GenerationResult SYSCALL( R4000GenContext^ context, int pass, int address, uint code, byte opcode, byte rs, byte rt, byte rd, byte shamt, byte function )
{
	int syscall = ( int )( ( code >> 6 ) & 0xFFFFF );

	BiosFunction^ biosFunction = context->Cpu->_syscalls[ syscall ];
	bool willCall;
	bool hasReturn;
	int paramCount;
	if( biosFunction != nullptr )
	{
		willCall = biosFunction->IsImplemented;
		hasReturn = biosFunction->HasReturn;
		paramCount = biosFunction->ParameterCount;

		if( biosFunction->IsImplemented == false )
		{
			if( pass == 0 )
			{
				Debug::WriteLine( String::Format( "R4000Generator: NID 0x{0:X8} {1} is not implemented",
					biosFunction->NID, biosFunction->Name ) );
			}
		}
	}
	else
	{
		willCall = false;
		hasReturn = false;
		paramCount = 0;

		if( pass == 0 )
			Debug::WriteLine( "R4000Generator: unregistered syscall attempt" );
	}
/*
	if( pass == 0 )
	{
	}
	else if( pass == 1 )
	{
		// It's important that we save what we think is the current PC
		// If we had an UpdatePc, it means a branch has updated it before us
		// and we need to save it - otherwise, save the PC following us
		context.ILGen.Emit( OpCodes.Ldarg_0 );
		if( context.UpdatePc == true )
			context.ILGen.Emit( OpCodes.Ldloc_2 );
		else
			context.ILGen.Emit( OpCodes.Ldc_I4, address + 4 );
		context.ILGen.Emit( OpCodes.Stfld, context.Core0Pc );

		if( willCall == true )
		{
			// Lame, but we need the object this gets called on and
			// there is no way to communicate what we know now to the final IL
			//context.Cpu._syscalls[ syscall ].Target.Target;
			context.ILGen.Emit( OpCodes.Ldarg_3 );
			context.ILGen.Emit( OpCodes.Ldc_I4, syscall );
			context.ILGen.Emit( OpCodes.Ldelem, typeof( BiosFunction ) );
			context.ILGen.Emit( OpCodes.Ldfld, context.BiosFunctionTarget );
			context.ILGen.Emit( OpCodes.Call, context.DelegateTargetGet );

			// Memory
			context.ILGen.Emit( OpCodes.Ldarg_1 );

			if( paramCount > 0 )
			{
				EmitLoadRegister( context, 4 );
				if( paramCount > 1 )
				{
					EmitLoadRegister( context, 5 );
					if( paramCount > 2 )
					{
						EmitLoadRegister( context, 6 );
						if( paramCount > 3 )
						{
							EmitLoadRegister( context, 7 );
							if( paramCount > 4 )
							{
								// Maybe this should always go?
								EmitLoadRegister( context, 29 );
							}
							else
								context.ILGen.Emit( OpCodes.Ldc_I4_0 );
						}
						else
						{
							context.ILGen.Emit( OpCodes.Ldc_I4_0 );
							context.ILGen.Emit( OpCodes.Ldc_I4_0 );
						}
					}
					else
					{
						context.ILGen.Emit( OpCodes.Ldc_I4_0 );
						context.ILGen.Emit( OpCodes.Ldc_I4_0 );
						context.ILGen.Emit( OpCodes.Ldc_I4_0 );
					}
				}
				else
				{
					context.ILGen.Emit( OpCodes.Ldc_I4_0 );
					context.ILGen.Emit( OpCodes.Ldc_I4_0 );
					context.ILGen.Emit( OpCodes.Ldc_I4_0 );
					context.ILGen.Emit( OpCodes.Ldc_I4_0 );
				}
			}
			else
			{
				context.ILGen.Emit( OpCodes.Ldc_I4_0 );
				context.ILGen.Emit( OpCodes.Ldc_I4_0 );
				context.ILGen.Emit( OpCodes.Ldc_I4_0 );
				context.ILGen.Emit( OpCodes.Ldc_I4_0 );
				context.ILGen.Emit( OpCodes.Ldc_I4_0 );
			}

			if( biosFunction.Target.Method.IsFinal == true )
				context.ILGen.Emit( OpCodes.Call, biosFunction.Target.Method );
			else
				context.ILGen.Emit( OpCodes.Callvirt, biosFunction.Target.Method );

			// Function returns a value - may need to ignore
			if( hasReturn == true )
				EmitStoreRegister( context, 2 );
			else
				context.ILGen.Emit( OpCodes.Pop );
		}
		else
		{
			// When we fail, we need to make sure to handle the cases where
			// the method has a return or else things could get even worse!
			if( biosFunction != null )
			{
				if( hasReturn == true )
				{
					context.ILGen.Emit( OpCodes.Ldc_I4, -1 );
					EmitStoreRegister( context, 2 );
				}
			}
		}
	}*/
	return GenerationResult::Syscall;
}

GenerationResult BREAK( R4000GenContext^ context, int pass, int address, uint code, byte opcode, byte rs, byte rt, byte rd, byte shamt, byte function )
{
	if( pass == 0 )
	{
		Debug::WriteLine( "R4000Generator: BREAK not implemented" );
	}
	else if( pass == 1 )
	{
	}
	return GenerationResult::Success;
}

GenerationResult SYNC( R4000GenContext^ context, int pass, int address, uint code, byte opcode, byte rs, byte rt, byte rd, byte shamt, byte function )
{
	// pg 629 - not needed?
	if( pass == 0 )
	{
		Debug::WriteLine( "R4000Generator: SYNC not implemented" );
	}
	else if( pass == 1 )
	{
	}
	return GenerationResult::Success;
}

GenerationResult COP1( R4000GenContext^ context, int pass, int address, uint code, byte opcode, byte rs, byte rt, ushort imm )
{
	if( pass == 0 )
	{
	}
	else if( pass == 1 )
	{
	}
	return GenerationResult::Invalid;
}

GenerationResult COP2( R4000GenContext^ context, int pass, int address, uint code, byte opcode, byte rs, byte rt, ushort imm )
{
	if( pass == 0 )
	{
	}
	else if( pass == 1 )
	{
	}
	return GenerationResult::Invalid;
}

GenerationResult HALT( R4000GenContext^ context, int pass, int address, uint code, byte opcode, byte rs, byte rt, byte rd, byte shamt, byte function )
{
	if( pass == 0 )
	{
		Debug::WriteLine( "R4000Generator: HALT not implemented" );
	}
	else if( pass == 1 )
	{
	}
	return GenerationResult::Success;
}

GenerationResult MFIC( R4000GenContext^ context, int pass, int address, uint code, byte opcode, byte rs, byte rt, byte rd, byte shamt, byte function )
{
	if( pass == 0 )
	{
		Debug::WriteLine( "R4000Generator: MFIC not implemented" );
	}
	else if( pass == 1 )
	{
	}
	return GenerationResult::Success;
}

GenerationResult MTIC( R4000GenContext^ context, int pass, int address, uint code, byte opcode, byte rs, byte rt, byte rd, byte shamt, byte function )
{
	if( pass == 0 )
	{
		Debug::WriteLine( "R4000Generator: MTIC not implemented" );
	}
	else if( pass == 1 )
	{
	}
	return GenerationResult::Success;
}
<|endoftext|>


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

#include "BitArray.h"
#include "ByteArray.h"

#include <cstddef>
#include <stdexcept>

#ifndef ZX_FAST_BIT_STORAGE
#include "BitHacks.h"
#include <algorithm>
#endif

namespace ZXing {

#ifndef ZX_FAST_BIT_STORAGE

bool
BitArray::isRange(int start, int end, bool value) const
{
	if (end < start || start < 0 || end > _size) {
		throw std::invalid_argument("BitArray::isRange(): Invalid range");
	}
	if (end == start) {
		return true; // empty range matches
	}
	end--; // will be easier to treat this as the last actually set bit -- inclusive
	int firstInt = start / 32;
	int lastInt = end / 32;
	for (int i = firstInt; i <= lastInt; i++) {
		int firstBit = i > firstInt ? 0 : start & 0x1F;
		int lastBit = i < lastInt ? 31 : end & 0x1F;
		// Ones from firstBit to lastBit, inclusive
		uint32_t mask = (2UL << lastBit) - (1UL << firstBit);
		// Return false if we're looking for 1s and the masked bits[i] isn't all 1s (that is,
		// equals the mask, or we're looking for 0s and the masked portion is not all 0s
		if ((_bits[i] & mask) != (value ? mask : 0U)) {
			return false;
		}
	}
	return true;
}

void
BitArray::appendBits(int value, int numBits)
{
	if (numBits < 0 || numBits > 32) {
		throw std::invalid_argument("BitArray::appendBits(): Num bits must be between 0 and 32");
	}
	int i = _size;
	_size += numBits;
	_bits.resize((_size + 31) / 32, 0);

	for (--numBits; numBits >= 0; --numBits, ++i) {
		_bits[i / 32] |= ((value >> numBits) & 1) << (i & 0x1F);
	}
}

void
BitArray::appendBit(bool bit)
{
	_bits.resize((_size + 1 + 31) / 32, 0);
	if (bit) {
		_bits[_size / 32] |= 1 << (_size & 0x1F);
	}
	_size++;
}

void
BitArray::appendBitArray(const BitArray& other)
{
	if (_bits.empty()) {
		*this = other.copy();
	}
	else if (other._size > 0) {
		unsigned offset = static_cast<unsigned>(_bits.size()) * 32 - _size;
		if (offset > 0) {
			auto buffer = other._bits;
			_bits.back() = (_bits.back() & (0xffffffff >> offset)) | (buffer.front() << (32 - offset));
			BitHacks::ShiftRight(buffer, offset);
			size_t prevBlockSize = _bits.size();
			_size += other._size;
			_bits.resize((_size + 31) / 32);
			std::copy_n(buffer.begin(), _bits.size() - prevBlockSize, _bits.begin() + prevBlockSize);
		}
		else {
			_size += other._size;
			_bits.insert(_bits.end(), other._bits.begin(), other._bits.end());
		}
	}
}
#endif

void
BitArray::bitwiseXOR(const BitArray& other)
{
	if (size() != other.size()) {
		throw std::invalid_argument("BitArray::xor(): Sizes don't match");
	}
	for (size_t i = 0; i < _bits.size(); i++) {
		// The last int could be incomplete (i.e. not have 32 bits in
		// it) but there is no problem since 0 XOR 0 == 0.
		_bits[i] ^= other._bits[i];
	}
}

ByteArray BitArray::toBytes(int bitOffset, int numBytes) const
{
	ByteArray res(numBytes);
	for (int i = 0; i < numBytes; i++)
		for (int j = 0; j < 8; j++)
			(res[i] <<= 1) |= get(bitOffset++);
	return res;
}

} // ZXing
<commit_msg>fix VC++ warning<commit_after>/*
* Copyright 2016 Nu-book Inc.
* Copyright 2016 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "BitArray.h"
#include "ByteArray.h"

#include <cstddef>
#include <stdexcept>

#ifndef ZX_FAST_BIT_STORAGE
#include "BitHacks.h"
#include <algorithm>
#endif

namespace ZXing {

#ifndef ZX_FAST_BIT_STORAGE

bool
BitArray::isRange(int start, int end, bool value) const
{
	if (end < start || start < 0 || end > _size) {
		throw std::invalid_argument("BitArray::isRange(): Invalid range");
	}
	if (end == start) {
		return true; // empty range matches
	}
	end--; // will be easier to treat this as the last actually set bit -- inclusive
	int firstInt = start / 32;
	int lastInt = end / 32;
	for (int i = firstInt; i <= lastInt; i++) {
		int firstBit = i > firstInt ? 0 : start & 0x1F;
		int lastBit = i < lastInt ? 31 : end & 0x1F;
		// Ones from firstBit to lastBit, inclusive
		uint32_t mask = (2UL << lastBit) - (1UL << firstBit);
		// Return false if we're looking for 1s and the masked bits[i] isn't all 1s (that is,
		// equals the mask, or we're looking for 0s and the masked portion is not all 0s
		if ((_bits[i] & mask) != (value ? mask : 0U)) {
			return false;
		}
	}
	return true;
}

void
BitArray::appendBits(int value, int numBits)
{
	if (numBits < 0 || numBits > 32) {
		throw std::invalid_argument("BitArray::appendBits(): Num bits must be between 0 and 32");
	}
	int i = _size;
	_size += numBits;
	_bits.resize((_size + 31) / 32, 0);

	for (--numBits; numBits >= 0; --numBits, ++i) {
		_bits[i / 32] |= ((value >> numBits) & 1) << (i & 0x1F);
	}
}

void
BitArray::appendBit(bool bit)
{
	_bits.resize((_size + 1 + 31) / 32, 0);
	if (bit) {
		_bits[_size / 32] |= 1 << (_size & 0x1F);
	}
	_size++;
}

void
BitArray::appendBitArray(const BitArray& other)
{
	if (_bits.empty()) {
		*this = other.copy();
	}
	else if (other._size > 0) {
		unsigned offset = static_cast<unsigned>(_bits.size()) * 32 - _size;
		if (offset > 0) {
			auto buffer = other._bits;
			_bits.back() = (_bits.back() & (0xffffffff >> offset)) | (buffer.front() << (32 - offset));
			BitHacks::ShiftRight(buffer, offset);
			size_t prevBlockSize = _bits.size();
			_size += other._size;
			_bits.resize((_size + 31) / 32);
			std::copy_n(buffer.begin(), _bits.size() - prevBlockSize, _bits.begin() + prevBlockSize);
		}
		else {
			_size += other._size;
			_bits.insert(_bits.end(), other._bits.begin(), other._bits.end());
		}
	}
}
#endif

void
BitArray::bitwiseXOR(const BitArray& other)
{
	if (size() != other.size()) {
		throw std::invalid_argument("BitArray::xor(): Sizes don't match");
	}
	for (size_t i = 0; i < _bits.size(); i++) {
		// The last int could be incomplete (i.e. not have 32 bits in
		// it) but there is no problem since 0 XOR 0 == 0.
		_bits[i] ^= other._bits[i];
	}
}

ByteArray BitArray::toBytes(int bitOffset, int numBytes) const
{
	ByteArray res(numBytes);
	for (int i = 0; i < numBytes; i++)
		for (int j = 0; j < 8; j++)
			(res[i] <<= 1) |= (get(bitOffset++) ? 1 : 0);
	return res;
}

} // ZXing
<|endoftext|>


<commit_before>//
// Wagon contacts: EMCAL Gustavo.Conesa.Balbastre@cern.ch
//
//
AliAnalysisTaskCaloTrackCorrelation *AddTaskCalorimeterQA(Bool_t kSimulation = kFALSE,
                                                          const char *suffix="default",
                                                          TString outputFile = "",
                                                          Int_t year = 2012,
                                                          Bool_t kPrintSettings = kFALSE)
{
  // Creates a PartCorr task for calorimeters performance studies, configures it and adds it to the analysis manager.

  if(kSimulation)
  {
    printf("AddTaskCalorimeterQA - CAREFUL : Triggered events not checked in simulation!! \n");
    TString ssuffix = suffix;
    if(!ssuffix.Contains("default")) return;
  }

  // Get the pointer to the existing analysis manager via the static access method.
  //==============================================================================
  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
  if (!mgr) {
    ::Error("AddTaskPartCorr", "No analysis manager to connect to.");
    return NULL;
  }

  // Check the analysis type using the event handlers connected to the analysis manager.
  //==============================================================================
  if (!mgr->GetInputEventHandler()) {
    ::Error("AddTaskPartCorr", "This task requires an input event handler");
    return NULL;
  }
  TString inputDataType = mgr->GetInputEventHandler()->GetDataType(); // can be "ESD" or "AOD"

  Bool_t kUseKinematics = (mgr->GetMCtruthEventHandler())?kTRUE:kFALSE;

  // Configure analysis
  //===========================================================================

  //Reader
  //For this particular analysis few things done by the reader.
  //Nothing else needs to be set.

  AliCaloTrackReader * reader = 0x0;
  if     (inputDataType.Contains("AOD")) reader = new AliCaloTrackAODReader();
  else if(inputDataType.Contains("ESD")) reader = new AliCaloTrackESDReader();
  //reader->SetDebug(10);//10 for lots of messages

  reader->SwitchOnEMCALCells();
  reader->SwitchOnEMCAL();
  reader->SwitchOnPHOSCells(); // For correlation plots
  reader->SwitchOnPHOS();      // For correlation plots
  reader->SetEMCALPtMin(0.);
  reader->SwitchOnCTS();
  reader->SetCTSPtMin  (0.);
  reader->SetZvertexCut(10.);

  if(kUseKinematics)
  {
    if(inputDataType == "ESD")
    {
      reader->SwitchOnStack();
      reader->SwitchOffAODMCParticles();
    }
    else if(inputDataType == "AOD")
    {
      reader->SwitchOffStack();
      reader->SwitchOnAODMCParticles();
    }
  }

  reader->SetDeltaAODFileName(""); //Do not create deltaAOD file, this analysis do not create branches.
  reader->SwitchOffWriteDeltaAOD()  ;

  if(kPrintSettings) reader->Print("");

  // *** Calorimeters Utils	***
  AliCalorimeterUtils *cu = new AliCalorimeterUtils;
  // Remove clusters close to borders, at least max energy cell is 1 cell away
  cu->SetNumberOfCellsFromEMCALBorder(1);

  AliEMCALRecoUtils* reco = cu->GetEMCALRecoUtils();
  reco->SwitchOnRejectExoticCell() ; // reject exotic cells, fill different histograms for exotic clusters and good clusters
  reco->SetExoticCellDiffTimeCut(10000); // Open
  reco->SetExoticCellFractionCut(0.95);  // 1-Ecross/Ecell > 0.95 -> out
  reco->SetExoticCellMinAmplitudeCut(0.75); // 750 MeV

  cu->SetDebug(-1);
  if(kPrintSettings) cu->Print("");

  // ##### Analysis algorithm settings ####

  AliAnaCalorimeterQA *emcalQA = new AliAnaCalorimeterQA();
  //emcalQA->SetDebug(10); //10 for lots of messages
  emcalQA->SetCalorimeter("EMCAL");
  if(kUseKinematics) emcalQA->SwitchOnDataMC() ;//Access MC stack and fill more histograms, AOD MC not implemented yet.
  else               emcalQA->SwitchOffDataMC() ;
  emcalQA->AddToHistogramsName("EMCAL_"); //Begining of histograms name
  emcalQA->SwitchOffFiducialCut();
  emcalQA->SwitchOnCorrelation();
  emcalQA->SwitchOffFillAllTH3Histogram();
  emcalQA->SwitchOffFillAllPositionHistogram();
  emcalQA->SwitchOffFillAllPositionHistogram2();
  emcalQA->SwitchOnStudyBadClusters();

  //Set Histrograms bins and ranges
  emcalQA->GetHistogramRanges()->SetHistoPtRangeAndNBins(0, 100, 200) ;
  emcalQA->GetHistogramRanges()->SetHistoFinePtRangeAndNBins(0, 10, 200) ; // bining for fhAmpId
  emcalQA->GetHistogramRanges()->SetHistoEtaRangeAndNBins(-0.71, 0.71, 200) ;

  if     (year==2010)
  {
    emcalQA->SetNumberOfModules(4);
    emcalQA->GetHistogramRanges()->SetHistoPhiRangeAndNBins(79*TMath::DegToRad(), 121*TMath::DegToRad(), 200) ;
    emcalQA->GetHistogramRanges()->SetHistoXRangeAndNBins(-230,90,120);
    emcalQA->GetHistogramRanges()->SetHistoYRangeAndNBins(370,450,40);
  }
  else if(year==2011)
  {
    emcalQA->SetNumberOfModules(10);
    emcalQA->GetHistogramRanges()->SetHistoPhiRangeAndNBins(79*TMath::DegToRad(), 191*TMath::DegToRad(), 200) ;
    emcalQA->GetHistogramRanges()->SetHistoXRangeAndNBins(-600,90,200);
    emcalQA->GetHistogramRanges()->SetHistoYRangeAndNBins(100,450,100);
  }
  else
  {
    emcalQA->SetNumberOfModules(12);
    emcalQA->GetHistogramRanges()->SetHistoPhiRangeAndNBins(79*TMath::DegToRad(), 181*TMath::DegToRad(), 200) ; // revise
    emcalQA->GetHistogramRanges()->SetHistoXRangeAndNBins(-700,90,200); // revise
    emcalQA->GetHistogramRanges()->SetHistoYRangeAndNBins(50,450,100);  // revise
  }

  emcalQA->GetHistogramRanges()->SetHistoMassRangeAndNBins(0., 1, 400) ;
  emcalQA->GetHistogramRanges()->SetHistoAsymmetryRangeAndNBins(0., 1. , 10 );
  emcalQA->GetHistogramRanges()->SetHistoPOverERangeAndNBins(0,3.,90);
  emcalQA->GetHistogramRanges()->SetHistodEdxRangeAndNBins(0.,200.,200);
  emcalQA->GetHistogramRanges()->SetHistodRRangeAndNBins(0.,0.15,150);
  emcalQA->GetHistogramRanges()->SetHistoTimeRangeAndNBins(300.,900,300);
  emcalQA->GetHistogramRanges()->SetHistoRatioRangeAndNBins(0.,2.,100);
  emcalQA->GetHistogramRanges()->SetHistoVertexDistRangeAndNBins(0.,500.,500);
  emcalQA->GetHistogramRanges()->SetHistoNClusterCellRangeAndNBins(0,500,500);
  emcalQA->GetHistogramRanges()->SetHistoZRangeAndNBins(-400,400,200);
  emcalQA->GetHistogramRanges()->SetHistoRRangeAndNBins(400,450,25);
  emcalQA->GetHistogramRanges()->SetHistoV0SignalRangeAndNBins(0,5000,500);
  emcalQA->GetHistogramRanges()->SetHistoV0MultiplicityRangeAndNBins(0,5000,500);
  emcalQA->GetHistogramRanges()->SetHistoTrackMultiplicityRangeAndNBins(0,5000,500);

  if(kPrintSettings) emcalQA->Print("");

  // #### Configure Maker ####
  AliAnaCaloTrackCorrMaker * maker = new AliAnaCaloTrackCorrMaker();
  maker->SetReader(reader);//pointer to reader
  maker->SetCaloUtils(cu); //pointer to calorimeter utils
  maker->AddAnalysis(emcalQA,0);
  maker->SetAnaDebug(-1)  ; // 0 to at least print the event number
  maker->SwitchOnHistogramsMaker()  ;
  maker->SwitchOffAODsMaker()  ;
  if(kPrintSettings) maker->Print("");

  printf("======================== \n");
  printf(" End Configuration of Calorimeter QA \n");
  printf("======================== \n");

  // Create task
  //===========================================================================
  AliAnalysisTaskCaloTrackCorrelation * task = new AliAnalysisTaskCaloTrackCorrelation (Form("CalorimeterPerformance_%s",suffix));
  task->SetConfigFileName(""); //Don't configure the analysis via configuration file.
  //task->SetDebugLevel(-1);
  task->SetAnalysisMaker(maker);
  task->SetBranches("ESD:AliESDRun.,AliESDHeader"); //just a trick to get Constantin's analysis to work
  mgr->AddTask(task);

  //Create containers
  //  AliAnalysisDataContainer *cout_pc = mgr->CreateContainer("Calo.Performance",TList::Class(),
  //							   AliAnalysisManager::kOutputContainer, "Calo.Performance.root");

  TString cname;
  if(outputFile.Length()==0)outputFile = AliAnalysisManager::GetCommonFileName();

  cname = Form("CaloQA_%s", suffix);
  AliAnalysisDataContainer *cout_pc   = mgr->CreateContainer(cname, TList::Class(),
                                                             AliAnalysisManager::kOutputContainer,
                                                             Form("%s:%s",outputFile.Data(),cname.Data()));

  cname = Form("CaloQACuts_%s", suffix);
  AliAnalysisDataContainer *cout_cuts = mgr->CreateContainer(cname, TList::Class(),
                                                             AliAnalysisManager::kParamContainer,
                                                             Form("%s:%s",outputFile.Data(),cname.Data()));

	//Form("%s:PartCorrCuts",outputfile.Data()));
  // Create ONLY the output containers for the data produced by the task.
  // Get and connect other common input/output containers via the manager as below
  //==============================================================================
  mgr->ConnectInput  (task, 0, mgr->GetCommonInputContainer());
  mgr->ConnectOutput (task, 1, cout_pc);
  mgr->ConnectOutput (task, 2, cout_cuts);

  return task;
}

<commit_msg>make sure trigger wagon is not activated for simulations; switch off some histograms in case of simulations<commit_after>//
// Wagon contacts: EMCAL Gustavo.Conesa.Balbastre@cern.ch
//
//
AliAnalysisTaskCaloTrackCorrelation *AddTaskCalorimeterQA(const char *suffix="default",
                                                          Bool_t kSimulation = kFALSE,
                                                          TString outputFile = "",
                                                          Int_t year = 2012,
                                                          Bool_t kPrintSettings = kFALSE)
{
  // Creates a PartCorr task for calorimeters performance studies, configures it and adds it to the analysis manager.

  // Get the pointer to the existing analysis manager via the static access method.
  //==============================================================================
  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
  if (!mgr) {
    ::Error("AddTaskPartCorr", "No analysis manager to connect to.");
    return NULL;
  }

  // Check the analysis type using the event handlers connected to the analysis manager.
  //==============================================================================
  if (!mgr->GetInputEventHandler()) {
    ::Error("AddTaskPartCorr", "This task requires an input event handler");
    return NULL;
  }

  TString inputDataType = mgr->GetInputEventHandler()->GetDataType(); // can be "ESD" or "AOD"

  Bool_t kUseKinematics = (mgr->GetMCtruthEventHandler())?kTRUE:kFALSE;

  TString ssuffix = suffix;
  if(kUseKinematics || kSimulation)
  {
    kSimulation = kTRUE;
    printf("AddTaskCalorimeterQA - CAREFUL : Triggered events not checked in simulation!! \n");
    if(!ssuffix.Contains("default")) return;
  }

  // Configure analysis
  //===========================================================================

  //Reader
  //For this particular analysis few things done by the reader.
  //Nothing else needs to be set.

  AliCaloTrackReader * reader = 0x0;
  if     (inputDataType.Contains("AOD")) reader = new AliCaloTrackAODReader();
  else if(inputDataType.Contains("ESD")) reader = new AliCaloTrackESDReader();
  //reader->SetDebug(10);//10 for lots of messages

  reader->SwitchOnEMCALCells();
  reader->SwitchOnEMCAL();
  reader->SwitchOnPHOSCells(); // For correlation plots
  reader->SwitchOnPHOS();      // For correlation plots
  reader->SetEMCALPtMin(0.);
  reader->SwitchOnCTS();
  reader->SetCTSPtMin  (0.);
  reader->SetZvertexCut(10.);

  if(kSimulation)
  {
    if(inputDataType == "ESD")
    {
      reader->SwitchOnStack();
      reader->SwitchOffAODMCParticles();
    }
    else if(inputDataType == "AOD")
    {
      reader->SwitchOffStack();
      reader->SwitchOnAODMCParticles();
    }
  }

  reader->SetDeltaAODFileName(""); //Do not create deltaAOD file, this analysis do not create branches.
  reader->SwitchOffWriteDeltaAOD()  ;

  if(!ssuffix.Contains("default"))
  {
    reader->SwitchOnTriggerPatchMatching();
    reader->SwitchOffBadTriggerEventsRemoval();
    reader->SetTriggerPatchTimeWindow(8,9);
    reader->SetEventTriggerThreshold(2.);
  }

  if(kPrintSettings) reader->Print("");

  // *** Calorimeters Utils	***
  AliCalorimeterUtils *cu = new AliCalorimeterUtils;
  // Remove clusters close to borders, at least max energy cell is 1 cell away
  cu->SetNumberOfCellsFromEMCALBorder(1);

  AliEMCALRecoUtils* reco = cu->GetEMCALRecoUtils();
  reco->SwitchOnRejectExoticCell() ; // reject exotic cells, fill different histograms for exotic clusters and good clusters
  reco->SetExoticCellDiffTimeCut(10000); // Open
  reco->SetExoticCellFractionCut(0.95);  // 1-Ecross/Ecell > 0.95 -> out
  reco->SetExoticCellMinAmplitudeCut(0.75); // 750 MeV

  cu->SetDebug(-1);
  if(kPrintSettings) cu->Print("");

  // ##### Analysis algorithm settings ####

  AliAnaCalorimeterQA *emcalQA = new AliAnaCalorimeterQA();
  //emcalQA->SetDebug(10); //10 for lots of messages
  emcalQA->SetCalorimeter("EMCAL");
  if(kSimulation)
  {
    emcalQA->SwitchOnDataMC() ;//Access MC stack and fill more histograms, AOD MC not implemented yet.
    emcalQA->SwitchOffStudyBadClusters();
    emcalQA->SwitchOffFillAllCellTimeHisto();
  }
  else
  {
    emcalQA->SwitchOffDataMC() ;
    emcalQA->SwitchOnStudyBadClusters();
    emcalQA->SwitchOnFillAllCellTimeHisto();
  }
  emcalQA->AddToHistogramsName("EMCAL_"); //Begining of histograms name
  emcalQA->SwitchOffFiducialCut();
  emcalQA->SwitchOnCorrelation();
  emcalQA->SwitchOffFillAllTH3Histogram();
  emcalQA->SwitchOffFillAllPositionHistogram();
  emcalQA->SwitchOffFillAllPositionHistogram2();

  //Set Histrograms bins and ranges
  emcalQA->GetHistogramRanges()->SetHistoPtRangeAndNBins(0, 100, 200) ;
  emcalQA->GetHistogramRanges()->SetHistoFinePtRangeAndNBins(0, 10, 200) ; // bining for fhAmpId
  emcalQA->GetHistogramRanges()->SetHistoEtaRangeAndNBins(-0.71, 0.71, 200) ;

  if     (year==2010)
  {
    emcalQA->SetNumberOfModules(4);
    emcalQA->GetHistogramRanges()->SetHistoPhiRangeAndNBins(79*TMath::DegToRad(), 121*TMath::DegToRad(), 200) ;
    emcalQA->GetHistogramRanges()->SetHistoXRangeAndNBins(-230,90,120);
    emcalQA->GetHistogramRanges()->SetHistoYRangeAndNBins(370,450,40);
  }
  else if(year==2011)
  {
    emcalQA->SetNumberOfModules(10);
    emcalQA->GetHistogramRanges()->SetHistoPhiRangeAndNBins(79*TMath::DegToRad(), 191*TMath::DegToRad(), 200) ;
    emcalQA->GetHistogramRanges()->SetHistoXRangeAndNBins(-600,90,200);
    emcalQA->GetHistogramRanges()->SetHistoYRangeAndNBins(100,450,100);
  }
  else
  {
    emcalQA->SetNumberOfModules(12);
    emcalQA->GetHistogramRanges()->SetHistoPhiRangeAndNBins(79*TMath::DegToRad(), 181*TMath::DegToRad(), 200) ; // revise
    emcalQA->GetHistogramRanges()->SetHistoXRangeAndNBins(-700,90,200); // revise
    emcalQA->GetHistogramRanges()->SetHistoYRangeAndNBins(50,450,100);  // revise
  }

  emcalQA->GetHistogramRanges()->SetHistoMassRangeAndNBins(0., 1, 400) ;
  emcalQA->GetHistogramRanges()->SetHistoAsymmetryRangeAndNBins(0., 1. , 10 );
  emcalQA->GetHistogramRanges()->SetHistoPOverERangeAndNBins(0,3.,90);
  emcalQA->GetHistogramRanges()->SetHistodEdxRangeAndNBins(0.,200.,200);
  emcalQA->GetHistogramRanges()->SetHistodRRangeAndNBins(0.,0.15,150);
  emcalQA->GetHistogramRanges()->SetHistoTimeRangeAndNBins(300.,900,300);
  emcalQA->GetHistogramRanges()->SetHistoRatioRangeAndNBins(0.,2.,100);
  emcalQA->GetHistogramRanges()->SetHistoVertexDistRangeAndNBins(0.,500.,500);
  emcalQA->GetHistogramRanges()->SetHistoNClusterCellRangeAndNBins(0,500,500);
  emcalQA->GetHistogramRanges()->SetHistoZRangeAndNBins(-400,400,200);
  emcalQA->GetHistogramRanges()->SetHistoRRangeAndNBins(400,450,25);
  emcalQA->GetHistogramRanges()->SetHistoV0SignalRangeAndNBins(0,5000,500);
  emcalQA->GetHistogramRanges()->SetHistoV0MultiplicityRangeAndNBins(0,5000,500);
  emcalQA->GetHistogramRanges()->SetHistoTrackMultiplicityRangeAndNBins(0,5000,500);

  if(kPrintSettings) emcalQA->Print("");

  // #### Configure Maker ####
  AliAnaCaloTrackCorrMaker * maker = new AliAnaCaloTrackCorrMaker();
  if(ssuffix.Contains("default")) maker->SwitchOffDataControlHistograms();
  else                            maker->SwitchOnDataControlHistograms();
  maker->SetReader(reader);//pointer to reader
  maker->SetCaloUtils(cu); //pointer to calorimeter utils
  maker->AddAnalysis(emcalQA,0);
  maker->SetAnaDebug(-1)  ; // 0 to at least print the event number
  maker->SwitchOnHistogramsMaker()  ;
  maker->SwitchOffAODsMaker()  ;
  if(kPrintSettings) maker->Print("");

  printf("======================== \n");
  printf(" End Configuration of Calorimeter QA \n");
  printf("======================== \n");

  // Create task
  //===========================================================================
  AliAnalysisTaskCaloTrackCorrelation * task = new AliAnalysisTaskCaloTrackCorrelation (Form("CalorimeterPerformance_%s",suffix));
  task->SetConfigFileName(""); //Don't configure the analysis via configuration file.
  //task->SetDebugLevel(-1);
  task->SetAnalysisMaker(maker);
  task->SetBranches("ESD:AliESDRun.,AliESDHeader"); //just a trick to get Constantin's analysis to work
  mgr->AddTask(task);

  //Create containers
  //  AliAnalysisDataContainer *cout_pc = mgr->CreateContainer("Calo.Performance",TList::Class(),
  //							   AliAnalysisManager::kOutputContainer, "Calo.Performance.root");

  TString cname;
  if(outputFile.Length()==0)outputFile = AliAnalysisManager::GetCommonFileName();

  cname = Form("CaloQA_%s", suffix);
  AliAnalysisDataContainer *cout_pc   = mgr->CreateContainer(cname, TList::Class(),
                                                             AliAnalysisManager::kOutputContainer,
                                                             Form("%s:%s",outputFile.Data(),cname.Data()));

//  cname = Form("CaloQACuts_%s", suffix);
//  AliAnalysisDataContainer *cout_cuts = mgr->CreateContainer(cname, TList::Class(),
//                                                             AliAnalysisManager::kParamContainer,
//                                                             Form("%s:%s",outputFile.Data(),cname.Data()));

	//Form("%s:PartCorrCuts",outputfile.Data()));
  // Create ONLY the output containers for the data produced by the task.
  // Get and connect other common input/output containers via the manager as below
  //==============================================================================
  mgr->ConnectInput  (task, 0, mgr->GetCommonInputContainer());
  mgr->ConnectOutput (task, 1, cout_pc);
//  mgr->ConnectOutput (task, 2, cout_cuts);

  return task;
}

<|endoftext|>