<commit_before>/*=========================================================================
  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

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

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

// Wrappers
#include "otbWrapperApplication.h"
#include "otbWrapperApplicationFactory.h"
#include "otbWrapperApplicationRegistry.h"
#include "otbWrapperAddProcessToWatchEvent.h"
#include "otbWrapperProxyParameter.h"
#include "otbWrapperParameterKey.h"
#include "itkStdStreamLogOutput.h"

namespace otb
{
namespace Wrapper
{

class CompositeTrain : public Application
{
public:
  /** Standard class typedefs. */
  typedef CompositeTrain            Self;
  typedef Application                   Superclass;
  typedef itk::SmartPointer<Self>       Pointer;
  typedef itk::SmartPointer<const Self> ConstPointer;

  /** Standard macro */
  itkNewMacro(Self);

  itkTypeMacro(CompositeTrain, otb::Application);

  /** Filters typedef */
  typedef itk::MemberCommand< Self >        AddProcessCommandType;

  typedef struct
    {
    Application::Pointer App;
    std::string Desc;
    } InternalApplication;

  typedef std::map<std::string, InternalApplication> InternalAppContainer;

protected:
  void LinkWatchers(itk::Object * itkNotUsed(caller), const itk::EventObject & event)
    {
    if (typeid(AddProcessToWatchEvent) == typeid( event ))
      {
      this->InvokeEvent(event);
      }
    }

  CompositeTrain()
    {
    m_LogOutput = itk::StdStreamLogOutput::New();
    m_LogOutput->SetStream(m_Oss);
    m_AddProcessCommand = AddProcessCommandType::New();
    m_AddProcessCommand->SetCallbackFunction(this, &CompositeTrain::LinkWatchers);
    }

private:

  InternalAppContainer m_AppContainer;

  /**
   * Method to instanciate and register a new internal application
   * \param appType Type of the application to instanciate
   * \param key Identifier associated to the created application
   * \param desc Description of the internal application
   */
  bool AddApplication(std::string appType, std::string key, std::string desc)
    {
    if (m_AppContainer.count(key))
      {
      otbAppLogWARNING("The requested identifier for internal application is already used ("<<key<<")");
      return false;
      }
    InternalAppContainer container;
    container.App = ApplicationRegistry::CreateApplication(appType);
    container.Desc = desc;
    // Setup logger
    container.App->GetLogger()->AddLogOutput(m_LogOutput);
    container.App->GetLogger()->SetTimeStampFormat(itk::LoggerBase::HUMANREADABLE);
    container.App->AddObserver(AddProcessToWatchEvent(), m_AddProcessCommand.GetPointer());
    m_AppContainer[key] = container;
    return true;
    }

  bool Connect(Application *app1, std::string key1, Application *app2, std::string key2)
  {
    Parameter* rawParam1 = app1->GetParameterByKey(key1, false);
    if (dynamic_cast<ProxyParameter*>(rawParam1))
      {
      otbAppLogWARNING("First parameter is already connected !");
      return false;
      }
    ProxyParameter::Pointer proxyParam = ProxyParameter::New();
    ProxyParameter::ProxyTargetType target;
    target.first = app2->GetParameterList();
    target.second = key2;
    proxyParam->SetTarget(target);
    proxyParam->SetName(rawParam1->GetName());
    proxyParam->SetDescription(rawParam1->GetDescription());

    return app1->GetParameterList()->SetParameter(proxyParam.GetPointer(),key1);
  }

  bool Connect(std::string key1, std::string key2)
  {
    size_t pos1 = key1.find('.');
    size_t pos2 = key2.find('.');
    Application *app1 = this;
    Application *app2 = this;
    std::string key1Check(key1);
    std::string key2Check(key2);

    if (pos1 != std::string::npos && m_AppContainer.count(key1.substr(0,pos1)))
      {
      app1 = m_AppContainer[key1.substr(0,pos1)].App;
      key1Check = key1.substr(pos1+1);
      }
    if (pos2 != std::string::npos && m_AppContainer.count(key2.substr(0,pos2)))
      {
      app2 = m_AppContainer[key2.substr(0,pos2)].App;
      key2Check = key2.substr(pos2+1);
      }

    return this->Connect(app1, key1Check, app2, key2Check);
  }

  void DoExecuteInternal(std::string key)
    {
    otbAppLogINFO(<< m_AppContainer[key].Desc <<"...");
    m_AppContainer[key].App->Execute();
    otbAppLogINFO(<< "\n" << m_Oss.str());
    m_Oss.str(std::string(""));
    }

  void DoInit() ITK_OVERRIDE
  {
    SetName("CompositeTrain");
    SetDescription("Composite application for classifier training.");
    SetDocName("Composite Train");
    SetDocLongDescription(" TODO");
    SetDocLimitations(" TODO");
    SetDocAuthors("OTB-Team");
    SetDocSeeAlso(" ");

    AddDocTag(Tags::Learning);

    this->AddApplication("PolygonClassStatistics", "polystat","Polygon analysis");

    this->AddApplication("SampleSelection", "select", "Sample selection");

    // share parameters with PolygonClassStatistics
    this->GetParameterList()->AddParameter(m_PolygonAnalysis->GetParameterByKey("in"));
    this->GetParameterList()->AddParameter(m_PolygonAnalysis->GetParameterByKey("vec"));
    //this->GetParameterList()->AddParameter(m_PolygonAnalysis->GetParameterByKey("field"));
    this->GetParameterList()->AddParameter(m_PolygonAnalysis->GetParameterByKey("layer"));

    AddParameter(ParameterType_Group, "sample", "Training and validation samples parameters");
    SetParameterDescription("sample",
                          "This group of parameters allows you to set training and validation sample lists parameters.");

    this->Connect("sample.vfn", "polystat.field");

    // share parameters with SampleSelection
    this->GetParameterList()->AddParameter(m_SampleSelection->GetParameterByKey("out"));
    this->GetParameterList()->AddParameter(m_SampleSelection->GetParameterByKey("strategy"));

    m_PolygonAnalysis->GetLogger()->AddLogOutput(m_LogOutput);
    m_PolygonAnalysis->GetLogger()->SetTimeStampFormat(itk::LoggerBase::HUMANREADABLE);
    m_SampleSelection->GetLogger()->AddLogOutput(m_LogOutput);
    m_SampleSelection->GetLogger()->SetTimeStampFormat(itk::LoggerBase::HUMANREADABLE);

    // Progress
    // Add the callback to be added when a AddProcessToWatch event is invoked
    m_PolygonAnalysis->AddObserver(AddProcessToWatchEvent(), m_AddProcessCommand.GetPointer());
    m_SampleSelection->AddObserver(AddProcessToWatchEvent(), m_AddProcessCommand.GetPointer());

    // Doc example parameter settings
    SetDocExampleParameterValue("io.in", "clLabeledImageQB123_1.tif");
    SetDocExampleParameterValue("io.out", "clLabeledImageQB123_1_CMR_r2_nodl_10_undl_7.tif");
    SetDocExampleParameterValue("ip.radius", "2");
    SetDocExampleParameterValue("ip.suvbool", "true");
    SetDocExampleParameterValue("ip.nodatalabel", "10");
    SetDocExampleParameterValue("ip.undecidedlabel", "7");
  }

  void DoUpdateParameters() ITK_OVERRIDE
  {
    // copy common values
    // "in" -> "SampleSelection.in"
    // "vec" -> "SampleSelection.in"
    // "field" -> "SampleSelection.in"
    // "layer" -> "SampleSelection.in"
    m_SampleSelection->SetParameterString("in",this->GetParameterString("in"));
    m_SampleSelection->SetParameterString("vec",this->GetParameterString("vec"));
    m_SampleSelection->SetParameterString("field",this->GetParameterString("sample.vfn"));
    m_SampleSelection->SetParameterInt("layer",this->GetParameterInt("layer"));

    if (HasValue("out"))
      {
      // TODO : get dirname, and prepare name of temporary output
      m_PolygonAnalysis->SetParameterString("out", std::string("foo.xml"));
      m_SampleSelection->SetParameterString("instats", std::string("foo.xml"));
      }

    // DoUpdateParameters on sub-application
    m_PolygonAnalysis->UpdateParameters();
    m_SampleSelection->UpdateParameters();
  }

  void DoExecute() ITK_OVERRIDE
  {
    this->DoExecuteInternal("polystat");
    this->DoExecuteInternal("select");
  }// END DoExecute()

  Application::Pointer m_PolygonAnalysis;

  Application::Pointer m_SampleSelection;

  itk::StdStreamLogOutput::Pointer  m_LogOutput;

  std::ostringstream m_Oss;

  AddProcessCommandType::Pointer    m_AddProcessCommand;

}; // END class CompositeTrain

}// END namespace wrapper
}// END namespace otb

OTB_APPLICATION_EXPORT(otb::Wrapper::CompositeTrain)
<commit_msg>ENH: work on common CompositeApp functions<commit_after>/*=========================================================================
  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

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

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

// Wrappers
#include "otbWrapperApplication.h"
#include "otbWrapperApplicationFactory.h"
#include "otbWrapperApplicationRegistry.h"
#include "otbWrapperAddProcessToWatchEvent.h"
#include "otbWrapperProxyParameter.h"
#include "otbWrapperParameterKey.h"
#include "itkStdStreamLogOutput.h"

namespace otb
{
namespace Wrapper
{

class CompositeTrain : public Application
{
public:
  /** Standard class typedefs. */
  typedef CompositeTrain            Self;
  typedef Application                   Superclass;
  typedef itk::SmartPointer<Self>       Pointer;
  typedef itk::SmartPointer<const Self> ConstPointer;

  /** Standard macro */
  itkNewMacro(Self);

  itkTypeMacro(CompositeTrain, otb::Application);

  /** Filters typedef */
  typedef itk::MemberCommand< Self >        AddProcessCommandType;

  typedef struct
    {
    Application::Pointer App;
    std::string Desc;
    } InternalApplication;

  typedef std::map<std::string, InternalApplication> InternalAppContainer;

protected:
  void LinkWatchers(itk::Object * itkNotUsed(caller), const itk::EventObject & event)
    {
    if (typeid(AddProcessToWatchEvent) == typeid( event ))
      {
      this->InvokeEvent(event);
      }
    }

  CompositeTrain()
    {
    m_LogOutput = itk::StdStreamLogOutput::New();
    m_LogOutput->SetStream(m_Oss);
    m_AddProcessCommand = AddProcessCommandType::New();
    m_AddProcessCommand->SetCallbackFunction(this, &CompositeTrain::LinkWatchers);
    }

private:

  /**
   * Method to instanciate and register a new internal application
   * \param appType Type of the application to instanciate
   * \param key Identifier associated to the created application
   * \param desc Description of the internal application
   */
  bool AddApplication(std::string appType, std::string key, std::string desc)
    {
    if (m_AppContainer.count(key))
      {
      otbAppLogWARNING("The requested identifier for internal application is already used ("<<key<<")");
      return false;
      }
    InternalApplication container;
    container.App = ApplicationRegistry::CreateApplication(appType);
    container.Desc = desc;
    // Setup logger
    container.App->GetLogger()->AddLogOutput(m_LogOutput);
    container.App->GetLogger()->SetTimeStampFormat(itk::LoggerBase::HUMANREADABLE);
    container.App->AddObserver(AddProcessToWatchEvent(), m_AddProcessCommand.GetPointer());
    m_AppContainer[key] = container;
    return true;
    }

  /**
   * Connect two existing parameters together. The first parameter will point to
   * the second parameter.
   */
  bool Connect(std::string fromKey, std::string toKey)
  {
    std::string key1(fromKey);
    std::string key2(toKey);
    Application *app1 = DecodeKey(key1);
    Application *app2 = DecodeKey(key2);

    Parameter* rawParam1 = app1->GetParameterByKey(key1, false);
    if (dynamic_cast<ProxyParameter*>(rawParam1))
      {
      otbAppLogWARNING("Parameter is already connected ! Override current connection");
      }
    ProxyParameter::Pointer proxyParam = ProxyParameter::New();
    ProxyParameter::ProxyTargetType target;
    target.first = app2->GetParameterList();
    target.second = key2;
    proxyParam->SetTarget(target);
    proxyParam->SetName(rawParam1->GetName());
    proxyParam->SetDescription(rawParam1->GetDescription());
    return app1->GetParameterList()->SetParameter(proxyParam.GetPointer(),key1);
  }

  /**
   * Share a parameter between the composite application and an internal application
   * The local parameter is created as a proxy to the internal parameter.
   * \param localKey New parameter key in the composite application
   * \param internalKey Key to the internal parameter to expose
   * \param name Name for the local parameter, if empty the target's name is used
   * \param desc Description for the local parameter, if empty the target's description is used
   */
  bool ShareParameter(std::string localKey,
                      std::string internalKey,
                      std::string name = std::string(),
                      std::string desc = std::string())
    {
    std::string internalKeyCheck(internalKey);
    Application *app = DecodeKey(internalKeyCheck);
    Parameter* rawTarget = app->GetParameterByKey(internalKeyCheck, false);

    ProxyParameter::Pointer proxyParam = ProxyParameter::New();
    ProxyParameter::ProxyTargetType target;
    target.first = app->GetParameterList();
    target.second = internalKeyCheck;
    proxyParam->SetTarget(target);
    proxyParam->SetName( name.empty() ? rawTarget->GetName() : name);
    proxyParam->SetDescription(desc.empty() ? rawTarget->GetDescription() : desc);
    return this->GetParameterList()->SetParameter(proxyParam.GetPointer(),localKey);
    }

  /**
   * Decode a key to extract potential prefix for internal applications
   * If a valid prefix (corresponding to an internal app) is found:
   *   - prefix is removed from the input key which is altered.
   *   - the function returns a pointer to the internal application
   * If no valid prefix is found, the input key is not modified, and the
   * function returns 'this'.
   */
  Application* DecodeKey(std::string &key)
    {
    Application *ret = this;
    size_t pos = key.find('.');
    if (pos != std::string::npos && m_AppContainer.count(key.substr(0,pos)))
      {
      ret = m_AppContainer[key.substr(0,pos)].App;
      key = key.substr(pos+1);
      }
    return ret;
    }

  void ExecuteInternal(std::string key)
    {
    otbAppLogINFO(<< m_AppContainer[key].Desc <<"...");
    m_AppContainer[key].App->Execute();
    otbAppLogINFO(<< "\n" << m_Oss.str());
    m_Oss.str(std::string(""));
    }

  void UpdateParametersInternal(std::string key)
    {
    m_AppContainer[key].App->UpdateParameters();
    }

  void DoInit() ITK_OVERRIDE
  {
    SetName("CompositeTrain");
    SetDescription("Composite application for classifier training.");
    SetDocName("Composite Train");
    SetDocLongDescription(" TODO");
    SetDocLimitations(" TODO");
    SetDocAuthors("OTB-Team");
    SetDocSeeAlso(" ");

    AddDocTag(Tags::Learning);

    AddParameter(ParameterType_Group, "sample", "Training and validation samples parameters");
    SetParameterDescription("sample", "This group of parameters allows you to "
      "set training and validation sample lists parameters.");

    AddApplication("PolygonClassStatistics", "polystat","Polygon analysis");
    AddApplication("SampleSelection", "select", "Sample selection");

    // share parameters with PolygonClassStatistics
    ShareParameter("in","polystat.in");
    ShareParameter("vec","polystat.vec");
    ShareParameter("layer","polystat.layer");
    ShareParameter("sample.vfn", "polystat.field");

    // share parameters with SampleSelection
    ShareParameter("out", "select.out");
    ShareParameter("strat", "select.strategy");

    // synchronize some parameters together:
    Connect("select.in",    "polystat.in");
    Connect("select.vec",   "polystat.vec");
    Connect("select.field", "polystat.field");
    Connect("select.layer", "polystat.layer");
    Connect("select.instats", "polystat.out");

    // Doc example parameter settings
    SetDocExampleParameterValue("io.in", "clLabeledImageQB123_1.tif");
    SetDocExampleParameterValue("io.out", "clLabeledImageQB123_1_CMR_r2_nodl_10_undl_7.tif");
    SetDocExampleParameterValue("ip.radius", "2");
    SetDocExampleParameterValue("ip.suvbool", "true");
    SetDocExampleParameterValue("ip.nodatalabel", "10");
    SetDocExampleParameterValue("ip.undecidedlabel", "7");
  }

  void DoUpdateParameters() ITK_OVERRIDE
  {
    if (HasValue("out"))
      {
      // TODO : get dirname, and prepare name of temporary output
      m_AppContainer["polystat"].App->SetParameterString("out", std::string("foo.xml"));
      }

    // DoUpdateParameters on sub-application
    UpdateParametersInternal("polystat");
    UpdateParametersInternal("select");
  }

  void DoExecute() ITK_OVERRIDE
  {
    this->ExecuteInternal("polystat");
    this->ExecuteInternal("select");
  }// END DoExecute()

  InternalAppContainer m_AppContainer;

  itk::StdStreamLogOutput::Pointer  m_LogOutput;

  std::ostringstream m_Oss;

  AddProcessCommandType::Pointer    m_AddProcessCommand;

}; // END class CompositeTrain

}// END namespace wrapper
}// END namespace otb

OTB_APPLICATION_EXPORT(otb::Wrapper::CompositeTrain)
<|endoftext|>


<commit_before>/*=========================================================================
 *
 *  Copyright Insight Software Consortium
 *
 *  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.txt
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *=========================================================================*/
#ifndef itkClampImageFilter_hxx
#define itkClampImageFilter_hxx

#include "itkClampImageFilter.h"
#include "itkProgressReporter.h"
#include "itkMath.h"

namespace itk
{

namespace Functor
{

template< typename TInput, typename TOutput >
Clamp< TInput, TOutput >
::Clamp() :
  m_LowerBound(NumericTraits< OutputType >::NonpositiveMin()),
  m_UpperBound(NumericTraits< OutputType >::max())
  {}

template< typename TInput, typename TOutput >
Clamp< TInput, TOutput >
::~Clamp() {}

template< typename TInput, typename TOutput >
typename Clamp< TInput, TOutput >::OutputType
Clamp< TInput, TOutput >
::GetLowerBound() const
  { return m_LowerBound; }

template< typename TInput, typename TOutput >
typename Clamp< TInput, TOutput >::OutputType
Clamp< TInput, TOutput >
::GetUpperBound() const
  { return m_UpperBound; }

template< typename TInput, typename TOutput >
void
Clamp< TInput, TOutput >
::SetBounds( const OutputType lowerBound, const OutputType upperBound)
  {
  if(lowerBound > upperBound)
    {
    itkGenericExceptionMacro("invalid bounds: [" << lowerBound << "; " << upperBound << "]");
    }

  m_LowerBound = lowerBound;
  m_UpperBound = upperBound;
  }

template< typename TInput, typename TOutput >
bool
Clamp< TInput, TOutput >
::operator!=( const Self & other ) const
  {
  return m_UpperBound != other.m_UpperBound
    || m_LowerBound != other.m_LowerBound;
  }

template< typename TInput, typename TOutput >
bool
Clamp< TInput, TOutput >
::operator==( const Self & other ) const
  {
  return !(*this != other);
  }

} // end namespace Functor

template <typename TInputImage, typename TOutputImage>
ClampImageFilter< TInputImage, TOutputImage >
::ClampImageFilter() {}

template <typename TInputImage, typename TOutputImage>
typename ClampImageFilter< TInputImage, TOutputImage >::OutputPixelType
ClampImageFilter< TInputImage, TOutputImage >
::GetLowerBound() const
  {
  return this->GetFunctor().GetLowerBound();
  }

template <typename TInputImage, typename TOutputImage>
typename ClampImageFilter< TInputImage, TOutputImage >::OutputPixelType
ClampImageFilter< TInputImage, TOutputImage >
::GetUpperBound() const
  {
  return this->GetFunctor().GetUpperBound();
  }

template <typename TInputImage, typename TOutputImage>
void
ClampImageFilter< TInputImage, TOutputImage >
::SetBounds(const OutputPixelType lowerBound, const OutputPixelType upperBound)
  {
  if ( Math::ExactlyEquals(lowerBound, this->GetFunctor().GetLowerBound()) && Math::ExactlyEquals(upperBound, this->GetFunctor().GetUpperBound()))
    {
    return;
    }

  this->GetFunctor().SetBounds(lowerBound, upperBound);
  this->Modified();
  }

template <typename TInputImage, typename TOutputImage>
void
ClampImageFilter< TInputImage, TOutputImage >
::GenerateData()
  {
  if( this->GetInPlace() && this->CanRunInPlace()
    && this->GetLowerBound() <= NumericTraits< OutputPixelType >::NonpositiveMin()
    && this->GetUpperBound() >= NumericTraits< OutputPixelType >::max() )
    {
    // If the filter is asked to run in-place, is able to run in-place,
    // and the specified bounds are equal to the output-type limits,
    // then there is nothing to do. To avoid iterating over all the pixels for
    // nothing, graft the input to the output, generate a fake progress and exit.
    this->AllocateOutputs();
    ProgressReporter progress(this, 0, 1);
    return;
    }
  Superclass::GenerateData();
  }

template <typename TInputImage, typename TOutputImage>
void
ClampImageFilter< TInputImage, TOutputImage >
::PrintSelf(std::ostream & os, Indent indent) const
  {
  Superclass::PrintSelf(os, indent);

  os << indent << "Lower bound: " << this->GetLowerBound() << std::endl;
  os << indent << "Upper bound: " << this->GetUpperBound() << std::endl;
  }
}

#endif
<commit_msg>BUG: Fix ivar type casting in PrintSelf.<commit_after>/*=========================================================================
 *
 *  Copyright Insight Software Consortium
 *
 *  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.txt
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *=========================================================================*/
#ifndef itkClampImageFilter_hxx
#define itkClampImageFilter_hxx

#include "itkClampImageFilter.h"
#include "itkProgressReporter.h"
#include "itkMath.h"

namespace itk
{

namespace Functor
{

template< typename TInput, typename TOutput >
Clamp< TInput, TOutput >
::Clamp() :
  m_LowerBound(NumericTraits< OutputType >::NonpositiveMin()),
  m_UpperBound(NumericTraits< OutputType >::max())
  {}

template< typename TInput, typename TOutput >
Clamp< TInput, TOutput >
::~Clamp() {}

template< typename TInput, typename TOutput >
typename Clamp< TInput, TOutput >::OutputType
Clamp< TInput, TOutput >
::GetLowerBound() const
  { return m_LowerBound; }

template< typename TInput, typename TOutput >
typename Clamp< TInput, TOutput >::OutputType
Clamp< TInput, TOutput >
::GetUpperBound() const
  { return m_UpperBound; }

template< typename TInput, typename TOutput >
void
Clamp< TInput, TOutput >
::SetBounds( const OutputType lowerBound, const OutputType upperBound)
  {
  if(lowerBound > upperBound)
    {
    itkGenericExceptionMacro("invalid bounds: [" << lowerBound << "; " << upperBound << "]");
    }

  m_LowerBound = lowerBound;
  m_UpperBound = upperBound;
  }

template< typename TInput, typename TOutput >
bool
Clamp< TInput, TOutput >
::operator!=( const Self & other ) const
  {
  return m_UpperBound != other.m_UpperBound
    || m_LowerBound != other.m_LowerBound;
  }

template< typename TInput, typename TOutput >
bool
Clamp< TInput, TOutput >
::operator==( const Self & other ) const
  {
  return !(*this != other);
  }

} // end namespace Functor

template <typename TInputImage, typename TOutputImage>
ClampImageFilter< TInputImage, TOutputImage >
::ClampImageFilter() {}

template <typename TInputImage, typename TOutputImage>
typename ClampImageFilter< TInputImage, TOutputImage >::OutputPixelType
ClampImageFilter< TInputImage, TOutputImage >
::GetLowerBound() const
  {
  return this->GetFunctor().GetLowerBound();
  }

template <typename TInputImage, typename TOutputImage>
typename ClampImageFilter< TInputImage, TOutputImage >::OutputPixelType
ClampImageFilter< TInputImage, TOutputImage >
::GetUpperBound() const
  {
  return this->GetFunctor().GetUpperBound();
  }

template <typename TInputImage, typename TOutputImage>
void
ClampImageFilter< TInputImage, TOutputImage >
::SetBounds(const OutputPixelType lowerBound, const OutputPixelType upperBound)
  {
  if ( Math::ExactlyEquals(lowerBound, this->GetFunctor().GetLowerBound()) && Math::ExactlyEquals(upperBound, this->GetFunctor().GetUpperBound()))
    {
    return;
    }

  this->GetFunctor().SetBounds(lowerBound, upperBound);
  this->Modified();
  }

template <typename TInputImage, typename TOutputImage>
void
ClampImageFilter< TInputImage, TOutputImage >
::GenerateData()
  {
  if( this->GetInPlace() && this->CanRunInPlace()
    && this->GetLowerBound() <= NumericTraits< OutputPixelType >::NonpositiveMin()
    && this->GetUpperBound() >= NumericTraits< OutputPixelType >::max() )
    {
    // If the filter is asked to run in-place, is able to run in-place,
    // and the specified bounds are equal to the output-type limits,
    // then there is nothing to do. To avoid iterating over all the pixels for
    // nothing, graft the input to the output, generate a fake progress and exit.
    this->AllocateOutputs();
    ProgressReporter progress(this, 0, 1);
    return;
    }
  Superclass::GenerateData();
  }

template <typename TInputImage, typename TOutputImage>
void
ClampImageFilter< TInputImage, TOutputImage >
::PrintSelf(std::ostream & os, Indent indent) const
  {
  Superclass::PrintSelf(os, indent);

  os << indent << "Lower bound: "
    << static_cast< typename NumericTraits< OutputPixelType >::PrintType >( this->GetLowerBound() ) << std::endl;
  os << indent << "Upper bound: "
    << static_cast< typename NumericTraits< OutputPixelType >::PrintType >( this->GetUpperBound() ) << std::endl;
  }
}

#endif
<|endoftext|>


<commit_before>/**
* Copyright (c) 2016 Dallin Wellington
*
*/

#include <gtest/gtest.h>

#include <Math/Vector.h>
#include <Math/Matrix4x4.h>

using namespace Monsoon::Math;

// --------------------------------------
// Vector2 Tests
// --------------------------------------

TEST(Vector2, Magnitude) {
	Vector2 vec = Vector2(10.0f, 5.0f);
	EXPECT_EQ(sqrt((10.0f * 10.0f) + (5.0f * 5.0f)), vec.Magnitude());
}

TEST(Vector2, Dot) {
	Vector2 vec1 = Vector2(10.0f, 5.0f);
	Vector2 vec2 = Vector2(2.0f, 7.0f);

	EXPECT_EQ((10.0f * 2.0f) + (5.0f * 7.0f), vec1 * vec2);
}

TEST(Vector2, Projection) {
	Vector2 vec1 = Vector2(1.0f, 100.0f);
	Vector2 vec2 = Vector2(100.0f, 0.0f);

	EXPECT_EQ(1.0f, vec1.Proj(vec2).Magnitude());
}

TEST(Vector2, Perpendicular) {
	Vector2 vec1 = Vector2(1.0f, 100.0f);
	Vector2 vec2 = Vector2(100.0f, 0.0f);

	EXPECT_EQ(100.0f, vec1.Perp(vec2).Magnitude());
}

TEST(Vector2, Unit) {
	Vector2 vec = Vector2(10.0f, 5.0f);

	//
	// Unit Vector Definition:
	//
	// Let v = <x, y>
	// |<x, y>| = <x/|v|,y/|v|>
	//
	EXPECT_EQ((10.0f / vec.Magnitude()), vec.Unit().mX);
	EXPECT_EQ((5.0f / vec.Magnitude()), vec.Unit().mY);
}

TEST(Vector2, VestorAddition) {
	Vector2 vec = Vector2(10.0f, 5.0f) + Vector2(2.0f, 7.0f);

	EXPECT_EQ(12, vec.mX);
	EXPECT_EQ(12, vec.mY);
}

TEST(Vector2, VectorSubtraction) {
	Vector2 vec = Vector2(10.0f, 5.0f) - Vector2(2.0f, 7.0f);

	EXPECT_EQ(8.0f, vec.mX);
	EXPECT_EQ(-2.0f, vec.mY);
}

TEST(Vector2, ScalarMultiplication) {
	Vector2 vec = Vector2(10.0f, 5.0f) * 2.0f;

	EXPECT_EQ(20.0f, vec.mX);
	EXPECT_EQ(10.0f, vec.mY);
}

TEST(Vector2, ScalarDivision) {
	Vector2 vec = Vector2(10.0f, 5.0f) / 2.0f;

	EXPECT_EQ(5.0f, vec.mX);
	EXPECT_EQ((5.0f / 2.0f), vec.mY);
}

// --------------------------------------
// Vector3 Tests
// --------------------------------------

TEST(Vector3, Magnitude) {
	Vector3 vec = Vector3(10.0f, 5.0f, 0.0f);
	EXPECT_EQ(sqrt((10.0f * 10.0f) + (5.0f * 5.0f)), vec.Magnitude());
}

TEST(Vector3, Dot) {
	Vector3 vec1 = Vector3(10.0f, 5.0f, 0.0f);
	Vector3 vec2 = Vector3(2.0f, 7.0f, 0.0f);

	EXPECT_EQ((10.0f * 2.0f) + (5.0f * 7.0f), vec1 * vec2);
}

TEST(Vector3, Projection) {
	Vector3 vec1 = Vector3(1.0f, 100.0f, 0.0f);
	Vector3 vec2 = Vector3(100.0f, 0.0f, 0.0f);

	EXPECT_EQ(1.0f, vec1.Proj(vec2).Magnitude());
}

TEST(Vector3, Perpendicular) {
	Vector3 vec1 = Vector3(1.0f, 100.0f, 0.0f);
	Vector3 vec2 = Vector3(100.0f, 0.0f, 0.0f);

	EXPECT_EQ(100.0f, vec1.Perp(vec2).Magnitude());
}

TEST(Vector3, Unit) {
	Vector3 vec = Vector3(10.0f, 5.0f, 2.0f);

	//
	// Unit Vector Definition:
	//
	// Let v = <x, y>
	// |<x, y>| = <x/|v|,y/|v|>
	//
	EXPECT_EQ((10.0f / vec.Magnitude()), vec.Unit().mX);
	EXPECT_EQ((5.0f / vec.Magnitude()), vec.Unit().mY);
	EXPECT_EQ((2.0f / vec.Magnitude()), vec.Unit().mZ);
}

TEST(Vector3, VestorAddition) {
	Vector3 vec = Vector3(10.0f, 5.0f, 2.0f) + Vector3(2.0f, 7.0f, -1.0f);

	EXPECT_EQ(12.0f, vec.mX);
	EXPECT_EQ(12.0f, vec.mY);
	EXPECT_EQ(1.0f, vec.mZ);
}

TEST(Vector3, VectorSubtraction) {
	Vector3 vec = Vector3(10.0f, 5.0f, 2.0f) - Vector3(2.0f, 7.0f, -1.0f);

	EXPECT_EQ(8.0f, vec.mX);
	EXPECT_EQ(-2.0f, vec.mY);
	EXPECT_EQ(3.0f, vec.mZ);
}

TEST(Vector3, ScalarMultiplication) {
	Vector3 vec = Vector3(10.0f, 5.0f, 2.0f) * 2.0f;

	EXPECT_EQ(20.0f, vec.mX);
	EXPECT_EQ(10.0f, vec.mY);
	EXPECT_EQ(4.0f, vec.mZ);
}

TEST(Vector3, ScalarDivision) {
	Vector3 vec = Vector3(10.0f, 5.0f, 2.0f) / 2.0f;

	EXPECT_EQ(5.0f, vec.mX);
	EXPECT_EQ((5.0f / 2.0f), vec.mY);
	EXPECT_EQ(1.0f, vec.mZ);
}

// --------------------------------------
// Vector4 Tests
// --------------------------------------

// --------------------------------------
// Matrix4x4 Tests
// --------------------------------------

/*
 * [I] * [I] = [I]
 */
TEST(Matrix4x4, IdentitySquared) {
	Matrix4x4 m1, m2;
	Matrix4x4 m3 = m1 * m2;

	EXPECT_EQ(1.0f, m3(0,0));
	EXPECT_EQ(1.0f, m3(1,1));
	EXPECT_EQ(1.0f, m3(2,2));
	EXPECT_EQ(1.0f, m3(3,3));
}

/*
 * [A] * [I] = [I] * [A] = [A]
 */
TEST(Matrix4x4, IdentityMultiplicationProperty) {
	float matrix[4][4] = {
		{ 1.0f, 0.0f, 0.0f, 0.0f },
		{ 0.0f, 1.0f, 0.0f, 0.0f },
		{ 0.0f, 0.0f, 1.0f, 0.0f },
		{ 10.0f, -30.0f, 50.0f, 1.0f }
	};

	Matrix4x4 m1(matrix);
	Matrix4x4 i;
	Matrix4x4 left = m1 * i;
	Matrix4x4 right = i * m1;

	EXPECT_EQ(true, m1 == left);
	EXPECT_EQ(true, m1 == right);
}

/*
* Test transpose functionality.
*/
TEST(Matrix4x4, Transpose) {
	float matrix[4][4] = {
		{ 1.0f, 0.0f, 0.0f, 0.0f },
		{ 0.0f, 1.0f, 0.0f, 0.0f },
		{ 0.0f, 0.0f, 1.0f, 0.0f },
		{ 10.0f, -30.0f, 50.0f, 1.0f }
	};

	float matrixT[4][4] = {
		{ 1.0f, 0.0f, 0.0f, 10.0f },
		{ 0.0f, 1.0f, 0.0f, -30.0f },
		{ 0.0f, 0.0f, 1.0f, 50.0f },
		{ 0.0f, 0.0f, 0.0f, 1.0f }
	};

	Matrix4x4 m1(matrix);
	Matrix4x4 m2(matrixT);

	EXPECT_EQ(true, m2 == m1.GetTranspose());
	m1.Transpose();
	EXPECT_EQ(true, m2 == m1);
}

/*
 * [I]^T = [I]
 */
TEST(Matrix4x4, IdentityTransposeProperty)
{
	Matrix4x4 m1;
	EXPECT_EQ(true, m1 == m1.GetTranspose());
	m1.Transpose();
	EXPECT_EQ(true, Matrix4x4() == m1);
}<commit_msg>Wrote test for transpose multiplication property. (A^T)(B^T)(C^T)==(ABC)^T<commit_after>/**
* Copyright (c) 2016 Dallin Wellington
*
*/

#include <gtest/gtest.h>

#include <Math/Vector.h>
#include <Math/Matrix4x4.h>

using namespace Monsoon::Math;

// --------------------------------------
// Vector2 Tests
// --------------------------------------

TEST(Vector2, Magnitude) {
	Vector2 vec = Vector2(10.0f, 5.0f);
	EXPECT_EQ(sqrt((10.0f * 10.0f) + (5.0f * 5.0f)), vec.Magnitude());
}

TEST(Vector2, Dot) {
	Vector2 vec1 = Vector2(10.0f, 5.0f);
	Vector2 vec2 = Vector2(2.0f, 7.0f);

	EXPECT_EQ((10.0f * 2.0f) + (5.0f * 7.0f), vec1 * vec2);
}

TEST(Vector2, Projection) {
	Vector2 vec1 = Vector2(1.0f, 100.0f);
	Vector2 vec2 = Vector2(100.0f, 0.0f);

	EXPECT_EQ(1.0f, vec1.Proj(vec2).Magnitude());
}

TEST(Vector2, Perpendicular) {
	Vector2 vec1 = Vector2(1.0f, 100.0f);
	Vector2 vec2 = Vector2(100.0f, 0.0f);

	EXPECT_EQ(100.0f, vec1.Perp(vec2).Magnitude());
}

TEST(Vector2, Unit) {
	Vector2 vec = Vector2(10.0f, 5.0f);

	//
	// Unit Vector Definition:
	//
	// Let v = <x, y>
	// |<x, y>| = <x/|v|,y/|v|>
	//
	EXPECT_EQ((10.0f / vec.Magnitude()), vec.Unit().mX);
	EXPECT_EQ((5.0f / vec.Magnitude()), vec.Unit().mY);
}

TEST(Vector2, VestorAddition) {
	Vector2 vec = Vector2(10.0f, 5.0f) + Vector2(2.0f, 7.0f);

	EXPECT_EQ(12, vec.mX);
	EXPECT_EQ(12, vec.mY);
}

TEST(Vector2, VectorSubtraction) {
	Vector2 vec = Vector2(10.0f, 5.0f) - Vector2(2.0f, 7.0f);

	EXPECT_EQ(8.0f, vec.mX);
	EXPECT_EQ(-2.0f, vec.mY);
}

TEST(Vector2, ScalarMultiplication) {
	Vector2 vec = Vector2(10.0f, 5.0f) * 2.0f;

	EXPECT_EQ(20.0f, vec.mX);
	EXPECT_EQ(10.0f, vec.mY);
}

TEST(Vector2, ScalarDivision) {
	Vector2 vec = Vector2(10.0f, 5.0f) / 2.0f;

	EXPECT_EQ(5.0f, vec.mX);
	EXPECT_EQ((5.0f / 2.0f), vec.mY);
}

// --------------------------------------
// Vector3 Tests
// --------------------------------------

TEST(Vector3, Magnitude) {
	Vector3 vec = Vector3(10.0f, 5.0f, 0.0f);
	EXPECT_EQ(sqrt((10.0f * 10.0f) + (5.0f * 5.0f)), vec.Magnitude());
}

TEST(Vector3, Dot) {
	Vector3 vec1 = Vector3(10.0f, 5.0f, 0.0f);
	Vector3 vec2 = Vector3(2.0f, 7.0f, 0.0f);

	EXPECT_EQ((10.0f * 2.0f) + (5.0f * 7.0f), vec1 * vec2);
}

TEST(Vector3, Projection) {
	Vector3 vec1 = Vector3(1.0f, 100.0f, 0.0f);
	Vector3 vec2 = Vector3(100.0f, 0.0f, 0.0f);

	EXPECT_EQ(1.0f, vec1.Proj(vec2).Magnitude());
}

TEST(Vector3, Perpendicular) {
	Vector3 vec1 = Vector3(1.0f, 100.0f, 0.0f);
	Vector3 vec2 = Vector3(100.0f, 0.0f, 0.0f);

	EXPECT_EQ(100.0f, vec1.Perp(vec2).Magnitude());
}

TEST(Vector3, Unit) {
	Vector3 vec = Vector3(10.0f, 5.0f, 2.0f);

	//
	// Unit Vector Definition:
	//
	// Let v = <x, y>
	// |<x, y>| = <x/|v|,y/|v|>
	//
	EXPECT_EQ((10.0f / vec.Magnitude()), vec.Unit().mX);
	EXPECT_EQ((5.0f / vec.Magnitude()), vec.Unit().mY);
	EXPECT_EQ((2.0f / vec.Magnitude()), vec.Unit().mZ);
}

TEST(Vector3, VestorAddition) {
	Vector3 vec = Vector3(10.0f, 5.0f, 2.0f) + Vector3(2.0f, 7.0f, -1.0f);

	EXPECT_EQ(12.0f, vec.mX);
	EXPECT_EQ(12.0f, vec.mY);
	EXPECT_EQ(1.0f, vec.mZ);
}

TEST(Vector3, VectorSubtraction) {
	Vector3 vec = Vector3(10.0f, 5.0f, 2.0f) - Vector3(2.0f, 7.0f, -1.0f);

	EXPECT_EQ(8.0f, vec.mX);
	EXPECT_EQ(-2.0f, vec.mY);
	EXPECT_EQ(3.0f, vec.mZ);
}

TEST(Vector3, ScalarMultiplication) {
	Vector3 vec = Vector3(10.0f, 5.0f, 2.0f) * 2.0f;

	EXPECT_EQ(20.0f, vec.mX);
	EXPECT_EQ(10.0f, vec.mY);
	EXPECT_EQ(4.0f, vec.mZ);
}

TEST(Vector3, ScalarDivision) {
	Vector3 vec = Vector3(10.0f, 5.0f, 2.0f) / 2.0f;

	EXPECT_EQ(5.0f, vec.mX);
	EXPECT_EQ((5.0f / 2.0f), vec.mY);
	EXPECT_EQ(1.0f, vec.mZ);
}

// --------------------------------------
// Vector4 Tests
// --------------------------------------

// --------------------------------------
// Matrix4x4 Tests
// --------------------------------------

/*
 * [I] * [I] = [I]
 */
TEST(Matrix4x4, IdentitySquared) {
	Matrix4x4 m1, m2;
	Matrix4x4 m3 = m1 * m2;

	EXPECT_EQ(1.0f, m3(0,0));
	EXPECT_EQ(1.0f, m3(1,1));
	EXPECT_EQ(1.0f, m3(2,2));
	EXPECT_EQ(1.0f, m3(3,3));
}

/*
 * [A] * [I] = [I] * [A] = [A]
 */
TEST(Matrix4x4, IdentityMultiplicationProperty) {
	float matrix[4][4] = {
		{ 1.0f, 0.0f, 0.0f, 0.0f },
		{ 0.0f, 1.0f, 0.0f, 0.0f },
		{ 0.0f, 0.0f, 1.0f, 0.0f },
		{ 10.0f, -30.0f, 50.0f, 1.0f }
	};

	Matrix4x4 m1(matrix);
	Matrix4x4 i;
	Matrix4x4 left = m1 * i;
	Matrix4x4 right = i * m1;

	EXPECT_EQ(true, m1 == left);
	EXPECT_EQ(true, m1 == right);
}

/*
* Test transpose functionality.
*/
TEST(Matrix4x4, Transpose) {
	float matrix[4][4] = {
		{ 1.0f, 0.0f, 0.0f, 0.0f },
		{ 0.0f, 1.0f, 0.0f, 0.0f },
		{ 0.0f, 0.0f, 1.0f, 0.0f },
		{ 10.0f, -30.0f, 50.0f, 1.0f }
	};

	float matrixT[4][4] = {
		{ 1.0f, 0.0f, 0.0f, 10.0f },
		{ 0.0f, 1.0f, 0.0f, -30.0f },
		{ 0.0f, 0.0f, 1.0f, 50.0f },
		{ 0.0f, 0.0f, 0.0f, 1.0f }
	};

	Matrix4x4 m1(matrix);
	Matrix4x4 m2(matrixT);

	EXPECT_EQ(true, m2 == m1.GetTranspose());
	m1.Transpose();
	EXPECT_EQ(true, m2 == m1);
}

/*
 * [I]^T = [I]
 */
TEST(Matrix4x4, IdentityTransposeProperty)
{
	Matrix4x4 m1;
	EXPECT_EQ(true, m1 == m1.GetTranspose());
	m1.Transpose();
	EXPECT_EQ(true, Matrix4x4() == m1);
}

/*
 * [A]^T*[B]^T*[C]^T = (ABC)^T
 */
TEST(Matrix4x4, TransposeMultiplicationProperty)
{
	float matrix[4][4] = {
		{ 1.0f, 0.0f, 0.0f, 0.0f },
		{ 0.0f, 1.0f, 0.0f, 0.0f },
		{ 0.0f, 0.0f, 1.0f, 0.0f },
		{ 10.0f, -30.0f, 50.0f, 1.0f }
	};

	float matrix2[4][4] = {
		{ 1.0f, 0.0f, 0.0f, 0.0f },
		{ 0.0f, 1.0f, 0.0f, 0.0f },
		{ 0.0f, 0.0f, 1.0f, 0.0f },
		{ 40.0f, 30.0f, 150.0f, 1.0f }
	};

	float matrix3[4][4] = {
		{ 1.0f, 0.0f, 0.0f, 0.0f },
		{ 0.0f, 1.0f, 0.0f, 0.0f },
		{ 0.0f, 0.0f, 1.0f, 0.0f },
		{ -310.0f, 90.0f, 45.0f, 1.0f }
	};

	Matrix4x4 m1(matrix), m2(matrix2), m3(matrix3);
	Matrix4x4 m4 = (m1 * m2 * m3).GetTranspose(); // ABC^T
	Matrix4x4 m5 = m1.GetTranspose() * m2.GetTranspose() * m3.GetTranspose();

	EXPECT_EQ(true, m4 == m5);
}<|endoftext|>


<commit_before>#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE api_tests
#define BOOST_TEST_MAIN
#define BOOST_TEST_LOG_LEVEL all

#include <boost/test/unit_test.hpp>
#include <iostream>
#include <string>
#include <vector>

#include "../Source/UCI.hpp"
#include "../Source/Search.hpp"
#include "../Source/Board.hpp"
#include "../Source/Evaluation.hpp"
#include "../Source/MoveList.hpp"

using namespace std;

BOOST_AUTO_TEST_CASE(UCI_sentPosition)
{
	cout << "Testing sentPosition function" << endl;
	BOOST_CHECK(UCI::sentPosition("position startpos moves e3e2") == false);
	BOOST_CHECK(UCI::sentPosition("position startpos moves e2e4") == true);
	BOOST_CHECK(UCI::sentPosition("position startpos") == false);
	BOOST_CHECK(UCI::sentPosition("position fen not a fen") == false);
}

BOOST_AUTO_TEST_CASE(evaluation_evaluateBoard)
{
	cout << "Testing evaluateBoard function" << endl;
	Board testBoard = Board("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1");
	BOOST_CHECK(Evaluation::evaluateBoard(testBoard) == 0); //evaluation should be 0 for initial board
	testBoard = Board("7k/8/8/8/8/8/8/7K w - - 0 1");
	BOOST_CHECK(Evaluation::evaluateBoard(testBoard) == 0); //no piece difference, symmetrical position
}

BOOST_AUTO_TEST_CASE(evaluation_CheckForDoublePawns)
{
    Evaluation::initpopCountOfByte(); //initialising look-up table
	cout << "Testing CheckForDoublePawns function" << endl;
	Board testBoard = Board("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1");
	BOOST_CHECK(Evaluation::CheckForDoublePawns(6, testBoard) == 0); //No double pawns for white
	BOOST_CHECK(Evaluation::CheckForDoublePawns(7, testBoard) == 0); //No double pawns for black
	testBoard = Board("8/8/4kP2/8/5P2/PP1P2P1/PPP1P2P/3K4 w - - 0 1");
	BOOST_CHECK(Evaluation::CheckForDoublePawns(6, testBoard) == 3); //3 sets of white double pawns
	testBoard = Board("8/8/4kP2/8/5P2/PPPPP1PP/PPP1P2P/3K4 w - - 0 1");
	BOOST_CHECK(Evaluation::CheckForDoublePawns(6, testBoard) == 6); //6 sets of white double pawns
	testBoard = Board("4k3/pppppppp/pppppppp/2b2b2/P5P1/P1qK1PP1/P4PP1/6q1 w - - 0 1");
	BOOST_CHECK(Evaluation::CheckForDoublePawns(7, testBoard) == 8); //8 sets of black double pawns
}

BOOST_AUTO_TEST_CASE(evaluation_rooksOnOpenFile)
{
	cout << "Testing rooksOnOpenFile function" << endl;
	Board testBoard = Board("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1");
	int temp = Evaluation::CheckForDoublePawns(6, testBoard); //check for double pawns initialises array of open files
	temp = Evaluation::CheckForDoublePawns(7, testBoard);
	BOOST_CHECK(Evaluation::rooksOnOpenFile(6, testBoard) == 0); //no rooks on open file for white
	BOOST_CHECK(Evaluation::rooksOnOpenFile(7, testBoard) == 0); //no rooks on open file for black
	testBoard = Board("r2k1r2/pp2p1pp/8/5P2/7P/8/1P6/RRRKRRRR w - - 0 1");
	temp = Evaluation::CheckForDoublePawns(6, testBoard);
	temp = Evaluation::CheckForDoublePawns(7, testBoard);
	BOOST_CHECK(Evaluation::rooksOnOpenFile(6, testBoard) == 4); //4 rooks on open file for white
	BOOST_CHECK(Evaluation::rooksOnOpenFile(7, testBoard) == 1); //1 rook on open file for black
}

BOOST_AUTO_TEST_CASE(board_inCheck)
{
	cout << "Testing inCheck function" << endl;
	Board testBoard = Board("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1");
	BOOST_CHECK(testBoard.inCheck(6) == false); //white isn't in check
	BOOST_CHECK(testBoard.inCheck(7) == false); //black isn't in check
	testBoard = Board("4k3/8/4r3/8/8/8/8/4K3 w - - 0 1");
	BOOST_CHECK(testBoard.inCheck(6) == true); //white is in check
	BOOST_CHECK(testBoard.inCheck(7) == false); //black isn't in check
	testBoard = Board("k1r5/8/1N6/8/8/8/8/4K3 w - - 0 1");
	BOOST_CHECK(testBoard.inCheck(7) == true); //black is in check
	BOOST_CHECK(testBoard.inCheck(6) == false); //white isn't in check
}

BOOST_AUTO_TEST_CASE(board_simpleMakeMove)
{
    cout << "Testing simpleMakeMove function" << endl;
    Board testBoard = Board("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1");
    pair<int, int> startPosition = make_pair('e' - 'a', '2' - '1');
    pair<int, int> endPosition = make_pair('e' - 'a', '4' - '1');
    testBoard.simpleMakeMove(startPosition, endPosition, ' ');
    BOOST_CHECK(testBoard.getPieceFromPos(4, 3) == 0); //pawn at e4
}

BOOST_AUTO_TEST_CASE(board_takePiece)
{
    cout << "Testing takePiece function" << endl;
    Board testBoard = Board("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1");
    testBoard.takePiece(make_pair(0, 0));
    BOOST_CHECK(testBoard.getPieceFromPos(0, 0) == -1); //piece has been removed
}

BOOST_AUTO_TEST_CASE(board_getPieceCode)
{
    cout << "Testing getPieceCode function" << endl;
    Board testBoard = Board("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1");
    BOOST_CHECK(testBoard.getPieceCode('p') == 0); //pawn
    BOOST_CHECK(testBoard.getPieceCode('P') == 0); //pawn
    BOOST_CHECK(testBoard.getPieceCode('r') == 1); //rook
    BOOST_CHECK(testBoard.getPieceCode('R') == 1); //rook
    BOOST_CHECK(testBoard.getPieceCode('n') == 2); //knight
    BOOST_CHECK(testBoard.getPieceCode('N') == 2); //knight
    BOOST_CHECK(testBoard.getPieceCode('b') == 3); //bishop
    BOOST_CHECK(testBoard.getPieceCode('B') == 3); //bishop
    BOOST_CHECK(testBoard.getPieceCode('q') == 4); //queen
    BOOST_CHECK(testBoard.getPieceCode('Q') == 4); //queen
    BOOST_CHECK(testBoard.getPieceCode('k') == 5); //king
    BOOST_CHECK(testBoard.getPieceCode('K') == 5); //king
}

int getColor(int x)
{
    if (x == 1) {
        return 6;
    }
    return 7;
}

int getLegalMoves(Board testBoard, int playerColor) {
    MoveList possibleMoves = MoveList(testBoard, getColor(playerColor));
    u64 castle = testBoard.getCastleOrEnpasent();
    int legalMoves = 0;
    while (true) {
        pair<bool, mov> get = possibleMoves.getNextMove();
        if (get.first) {
            testBoard.makeMov(get.second);
            if (testBoard.inCheck(getColor(playerColor)) == false) {
                legalMoves++;
            }
            testBoard.unMakeMov(get.second, castle);
        } else {
            break;
        }
    }
    return legalMoves;
}

BOOST_AUTO_TEST_CASE(MoveList_generateMoves)
{
	cout << "Testing MoveList class" << endl;
    Board testBoard = Board("k5R1/7R/8/8/8/8/8/K7 b - - 0 1");
    BOOST_CHECK(getLegalMoves(testBoard, -1) == 0); //black is check mated
    testBoard = Board("k7/8/8/8/8/8/8/K7 w - - 0 1");
    BOOST_CHECK(getLegalMoves(testBoard, 1) == 3); //only piece is king in corner
    testBoard = Board("k7/8/8/8/4K3/8/8/8 w - - 0 1");
    BOOST_CHECK(getLegalMoves(testBoard, 1) == 8); //only piece is king in center
}

BOOST_AUTO_TEST_CASE(search_RootAlphaBeta)
{
    cout << "Testing search" << endl;
    Board testBoard = Board("k7/pppp4/8/8/8/8/8/K4R2 w - - 0 1");
    Search searchClass;
    BOOST_CHECK(searchClass.RootAlphaBeta(testBoard, 1, 4) == "f1f8"); //it should find the checkmate for white
}
<commit_msg>Added Perft test for move generation<commit_after>#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE api_tests
#define BOOST_TEST_MAIN
#define BOOST_TEST_LOG_LEVEL all

#include <boost/test/unit_test.hpp>
#include <iostream>
#include <string>
#include <vector>

#include "../Source/UCI.hpp"
#include "../Source/Search.hpp"
#include "../Source/Board.hpp"
#include "../Source/Evaluation.hpp"
#include "../Source/MoveList.hpp"

using namespace std;

BOOST_AUTO_TEST_CASE(UCI_sentPosition)
{
	cout << "Testing sentPosition function" << endl;
	BOOST_CHECK(UCI::sentPosition("position startpos moves e3e2") == false);
	BOOST_CHECK(UCI::sentPosition("position startpos moves e2e4") == true);
	BOOST_CHECK(UCI::sentPosition("position startpos") == false);
	BOOST_CHECK(UCI::sentPosition("position fen not a fen") == false);
}

BOOST_AUTO_TEST_CASE(evaluation_evaluateBoard)
{
	cout << "Testing evaluateBoard function" << endl;
	Board testBoard = Board("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1");
	BOOST_CHECK(Evaluation::evaluateBoard(testBoard) == 0); //evaluation should be 0 for initial board
	testBoard = Board("7k/8/8/8/8/8/8/7K w - - 0 1");
	BOOST_CHECK(Evaluation::evaluateBoard(testBoard) == 0); //no piece difference, symmetrical position
}

BOOST_AUTO_TEST_CASE(evaluation_CheckForDoublePawns)
{
    Evaluation::initpopCountOfByte(); //initialising look-up table
	cout << "Testing CheckForDoublePawns function" << endl;
	Board testBoard = Board("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1");
	BOOST_CHECK(Evaluation::CheckForDoublePawns(6, testBoard) == 0); //No double pawns for white
	BOOST_CHECK(Evaluation::CheckForDoublePawns(7, testBoard) == 0); //No double pawns for black
	testBoard = Board("8/8/4kP2/8/5P2/PP1P2P1/PPP1P2P/3K4 w - - 0 1");
	BOOST_CHECK(Evaluation::CheckForDoublePawns(6, testBoard) == 3); //3 sets of white double pawns
	testBoard = Board("8/8/4kP2/8/5P2/PPPPP1PP/PPP1P2P/3K4 w - - 0 1");
	BOOST_CHECK(Evaluation::CheckForDoublePawns(6, testBoard) == 6); //6 sets of white double pawns
	testBoard = Board("4k3/pppppppp/pppppppp/2b2b2/P5P1/P1qK1PP1/P4PP1/6q1 w - - 0 1");
	BOOST_CHECK(Evaluation::CheckForDoublePawns(7, testBoard) == 8); //8 sets of black double pawns
}

BOOST_AUTO_TEST_CASE(evaluation_rooksOnOpenFile)
{
	cout << "Testing rooksOnOpenFile function" << endl;
	Board testBoard = Board("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1");
	int temp = Evaluation::CheckForDoublePawns(6, testBoard); //check for double pawns initialises array of open files
	temp = Evaluation::CheckForDoublePawns(7, testBoard);
	BOOST_CHECK(Evaluation::rooksOnOpenFile(6, testBoard) == 0); //no rooks on open file for white
	BOOST_CHECK(Evaluation::rooksOnOpenFile(7, testBoard) == 0); //no rooks on open file for black
	testBoard = Board("r2k1r2/pp2p1pp/8/5P2/7P/8/1P6/RRRKRRRR w - - 0 1");
	temp = Evaluation::CheckForDoublePawns(6, testBoard);
	temp = Evaluation::CheckForDoublePawns(7, testBoard);
	BOOST_CHECK(Evaluation::rooksOnOpenFile(6, testBoard) == 4); //4 rooks on open file for white
	BOOST_CHECK(Evaluation::rooksOnOpenFile(7, testBoard) == 1); //1 rook on open file for black
}

BOOST_AUTO_TEST_CASE(board_inCheck)
{
	cout << "Testing inCheck function" << endl;
	Board testBoard = Board("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1");
	BOOST_CHECK(testBoard.inCheck(6) == false); //white isn't in check
	BOOST_CHECK(testBoard.inCheck(7) == false); //black isn't in check
	testBoard = Board("4k3/8/4r3/8/8/8/8/4K3 w - - 0 1");
	BOOST_CHECK(testBoard.inCheck(6) == true); //white is in check
	BOOST_CHECK(testBoard.inCheck(7) == false); //black isn't in check
	testBoard = Board("k1r5/8/1N6/8/8/8/8/4K3 w - - 0 1");
	BOOST_CHECK(testBoard.inCheck(7) == true); //black is in check
	BOOST_CHECK(testBoard.inCheck(6) == false); //white isn't in check
}

BOOST_AUTO_TEST_CASE(board_simpleMakeMove)
{
    cout << "Testing simpleMakeMove function" << endl;
    Board testBoard = Board("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1");
    pair<int, int> startPosition = make_pair('e' - 'a', '2' - '1');
    pair<int, int> endPosition = make_pair('e' - 'a', '4' - '1');
    testBoard.simpleMakeMove(startPosition, endPosition, ' ');
    BOOST_CHECK(testBoard.getPieceFromPos(4, 3) == 0); //pawn at e4
}

BOOST_AUTO_TEST_CASE(board_takePiece)
{
    cout << "Testing takePiece function" << endl;
    Board testBoard = Board("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1");
    testBoard.takePiece(make_pair(0, 0));
    BOOST_CHECK(testBoard.getPieceFromPos(0, 0) == -1); //piece has been removed
}

BOOST_AUTO_TEST_CASE(board_getPieceCode)
{
    cout << "Testing getPieceCode function" << endl;
    Board testBoard = Board("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1");
    BOOST_CHECK(testBoard.getPieceCode('p') == 0); //pawn
    BOOST_CHECK(testBoard.getPieceCode('P') == 0); //pawn
    BOOST_CHECK(testBoard.getPieceCode('r') == 1); //rook
    BOOST_CHECK(testBoard.getPieceCode('R') == 1); //rook
    BOOST_CHECK(testBoard.getPieceCode('n') == 2); //knight
    BOOST_CHECK(testBoard.getPieceCode('N') == 2); //knight
    BOOST_CHECK(testBoard.getPieceCode('b') == 3); //bishop
    BOOST_CHECK(testBoard.getPieceCode('B') == 3); //bishop
    BOOST_CHECK(testBoard.getPieceCode('q') == 4); //queen
    BOOST_CHECK(testBoard.getPieceCode('Q') == 4); //queen
    BOOST_CHECK(testBoard.getPieceCode('k') == 5); //king
    BOOST_CHECK(testBoard.getPieceCode('K') == 5); //king
}

int getColor(int x)
{
    if (x == 1) {
        return 6;
    }
    return 7;
}

int getLegalMoves(Board testBoard, int playerColor) {
    MoveList possibleMoves = MoveList(testBoard, getColor(playerColor));
    u64 castle = testBoard.getCastleOrEnpasent();
    int legalMoves = 0;
    while (true) {
        pair<bool, mov> get = possibleMoves.getNextMove();
        if (get.first) {
            testBoard.makeMov(get.second);
            if (testBoard.inCheck(getColor(playerColor)) == false) {
                legalMoves++;
            }
            testBoard.unMakeMov(get.second, castle);
        } else {
            break;
        }
    }
    return legalMoves;
}

BOOST_AUTO_TEST_CASE(MoveList_generateMoves)
{
	cout << "Testing MoveList class" << endl;
    Board testBoard = Board("k5R1/7R/8/8/8/8/8/K7 b - - 0 1");
    BOOST_CHECK(getLegalMoves(testBoard, -1) == 0); //black is check mated
    testBoard = Board("k7/8/8/8/8/8/8/K7 w - - 0 1");
    BOOST_CHECK(getLegalMoves(testBoard, 1) == 3); //only piece is king in corner
    testBoard = Board("k7/8/8/8/4K3/8/8/8 w - - 0 1");
    BOOST_CHECK(getLegalMoves(testBoard, 1) == 8); //only piece is king in center
}

BOOST_AUTO_TEST_CASE(search_RootAlphaBeta)
{
    cout << "Testing search" << endl;
    Board testBoard = Board("k7/pppp4/8/8/8/8/8/K4R2 w - - 0 1");
    BOOST_CHECK(Search::RootAlphaBeta(testBoard, 1, 4) == "f1f8"); //it should find the checkmate for white
}

//Perft is good for verifying the correctness of the move generation, generate all the leaf nodes at a given depth from a known position.
//This also shows how fast the move generation works in relation to other engines (slow, magic bitboards would speed up move generation)
u64 Perft(int depth, Board& gameBoard, int playerColor)
{
    if (depth == 0) {
        return 1;
    }

    u64 nodes = 0;
    u64 castle = gameBoard.getCastleOrEnpasent();

    MoveList possibleMoves(gameBoard, getColor(playerColor));
    while (true) {
        pair<bool, mov> get = possibleMoves.getNextMove();
        if (get.first) {
            gameBoard.makeMov(get.second);
            if (gameBoard.inCheck(getColor(playerColor)) == false) {
                nodes += Perft(depth - 1, gameBoard, playerColor*-1);
            }
            gameBoard.unMakeMov(get.second, castle);
        } else {
            break;
        }
    }
    return nodes;
}

BOOST_AUTO_TEST_CASE(perft_Test)
{
    cout << "Testing move generation (perft), this is slow" << endl;
    Board testBoard = Board("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"); //initial position
    BOOST_CHECK(Perft(4, testBoard, 1) == 197281); //Known value from the chess programming wiki http://chessprogramming.wikispaces.com/Perft+Results
    testBoard = Board("r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq -");
    BOOST_CHECK(Perft(4, testBoard, 1) == 4085603);
    testBoard = Board("8/2p5/3p4/KP5r/1R3p1k/8/4P1P1/8 w - -");
    BOOST_CHECK(Perft(5, testBoard, 1) == 674624);
    testBoard = Board("r2q1rk1/pP1p2pp/Q4n2/bbp1p3/Np6/1B3NBn/pPPP1PPP/R3K2R b KQ - 0 1");
    BOOST_CHECK(Perft(4, testBoard, -1) == 422333);
    testBoard = Board("rnbqkb1r/pp1p1ppp/2p5/4P3/2B5/8/PPP1NnPP/RNBQK2R w KQkq - 0 6");
    BOOST_CHECK(Perft(3, testBoard, 1) == 53392);
    testBoard = Board("r4rk1/1pp1qppp/p1np1n2/2b1p1B1/2B1P1b1/P1NP1N2/1PP1QPPP/R4RK1 w - - 0 10");
    BOOST_CHECK(Perft(4, testBoard, 1) == 3894594);
}
<|endoftext|>


<commit_before>#include "drawable.h"
#include <foundation/memory.h>
#include "idrawable_geometry.h"
#include <cmath>

namespace bowtie
{

////////////////////////////////
// Public interface.

Drawable::Drawable(Allocator& allocator, IDrawableGeometry& geometry) : _allocator(allocator), _geometry(geometry),
	 _pivot(0, 0), _position(0, 0), _render_state_changed(false), _rotation(0.7f)
{
}

Drawable::Drawable(const Drawable& other) : _allocator(other._allocator), _geometry(other._geometry.clone(_allocator)),
	_pivot(0, 0), _position(other._position), _render_state_changed(false), _rotation(0.7f)
{
}

Drawable::~Drawable()
{
	_allocator.destroy(&_geometry);
}

const Color& Drawable::color() const
{
	return _geometry.color();
}

IDrawableGeometry& Drawable::geometry()
{
	return _geometry;
}

const IDrawableGeometry& Drawable::geometry() const
{
	return _geometry;
}

bool Drawable::geometry_changed() const
{
	return _geometry.has_changed();
}

ResourceHandle Drawable::geometry_handle() const
{
	return _geometry_handle;
}

Matrix4 Drawable::model_matrix() const
{
	auto p = Matrix4();
	p[3][0] = (float)_pivot.x;
	p[3][1] = (float)_pivot.y;

	auto p_inv = Matrix4();
	p[3][0] = -(float)_pivot.x;
	p[3][1] = -(float)_pivot.y;

	auto r = Matrix4();
	r[0][0] = cos(_rotation);
	r[1][0] = -sin(_rotation);
	r[0][1] = sin(_rotation);
	r[1][1] = cos(_rotation);

	auto t = Matrix4();
	t[3][0] = _position.x;
	t[3][1] = _position.y;

	if (_pivot.x == 0 && _pivot.y == 0)
		return r * t;
	else
		return p * r * p_inv * t;
}

const Vector2i& Drawable::pivot() const
{
	return _pivot;
}

const Vector2& Drawable::position() const
{
	return _position;
}

ResourceHandle Drawable::render_handle() const
{
	return _render_handle;
}

void Drawable::reset_geometry_changed()
{
	_geometry.reset_has_changed();
}

void Drawable::reset_state_changed()
{
	_render_state_changed = false;
}

float Drawable::rotation() const
{
	return _rotation;
}

void Drawable::set_color(const Color& color)
{
	_geometry.set_color(color);
}

void Drawable::set_geometry_handle(ResourceHandle handle)
{
	_geometry_handle = handle;
}

void Drawable::set_pivot(const Vector2i& pivot)
{
	_pivot = pivot;
	_render_state_changed = true;
}

void Drawable::set_position(const Vector2& position)
{
	_position = position;
	_render_state_changed = true;
}

void Drawable::set_render_handle(ResourceHandle handle)
{
	assert(_render_handle.type == ResourceHandle::NotInitialized && "Trying to reset already initliaized drawable render handle.");
	_render_handle = handle;
}

void Drawable::set_rotation(float rotation)
{
	_rotation = rotation;
	_render_state_changed = true;
}

void Drawable::set_shader(ResourceHandle shader)
{
	_shader = shader;
	_render_state_changed = true;
}

ResourceHandle Drawable::shader() const
{
	return _shader;
}

bool Drawable::state_changed() const
{
	return _render_state_changed;
}

}
<commit_msg>Removed debug rotation.<commit_after>#include "drawable.h"
#include <foundation/memory.h>
#include "idrawable_geometry.h"
#include <cmath>

namespace bowtie
{

////////////////////////////////
// Public interface.

Drawable::Drawable(Allocator& allocator, IDrawableGeometry& geometry) : _allocator(allocator), _geometry(geometry),
	 _pivot(0, 0), _position(0, 0), _render_state_changed(false), _rotation(0.0f)
{
}

Drawable::Drawable(const Drawable& other) : _allocator(other._allocator), _geometry(other._geometry.clone(_allocator)),
	_pivot(0, 0), _position(other._position), _render_state_changed(false), _rotation(0.0f)
{
}

Drawable::~Drawable()
{
	_allocator.destroy(&_geometry);
}

const Color& Drawable::color() const
{
	return _geometry.color();
}

IDrawableGeometry& Drawable::geometry()
{
	return _geometry;
}

const IDrawableGeometry& Drawable::geometry() const
{
	return _geometry;
}

bool Drawable::geometry_changed() const
{
	return _geometry.has_changed();
}

ResourceHandle Drawable::geometry_handle() const
{
	return _geometry_handle;
}

Matrix4 Drawable::model_matrix() const
{
	auto p = Matrix4();
	p[3][0] = (float)_pivot.x;
	p[3][1] = (float)_pivot.y;

	auto p_inv = Matrix4();
	p[3][0] = -(float)_pivot.x;
	p[3][1] = -(float)_pivot.y;

	auto r = Matrix4();
	r[0][0] = cos(_rotation);
	r[1][0] = -sin(_rotation);
	r[0][1] = sin(_rotation);
	r[1][1] = cos(_rotation);

	auto t = Matrix4();
	t[3][0] = _position.x;
	t[3][1] = _position.y;

	if (_pivot.x == 0 && _pivot.y == 0)
		return r * t;
	else
		return p * r * p_inv * t;
}

const Vector2i& Drawable::pivot() const
{
	return _pivot;
}

const Vector2& Drawable::position() const
{
	return _position;
}

ResourceHandle Drawable::render_handle() const
{
	return _render_handle;
}

void Drawable::reset_geometry_changed()
{
	_geometry.reset_has_changed();
}

void Drawable::reset_state_changed()
{
	_render_state_changed = false;
}

float Drawable::rotation() const
{
	return _rotation;
}

void Drawable::set_color(const Color& color)
{
	_geometry.set_color(color);
}

void Drawable::set_geometry_handle(ResourceHandle handle)
{
	_geometry_handle = handle;
}

void Drawable::set_pivot(const Vector2i& pivot)
{
	_pivot = pivot;
	_render_state_changed = true;
}

void Drawable::set_position(const Vector2& position)
{
	_position = position;
	_render_state_changed = true;
}

void Drawable::set_render_handle(ResourceHandle handle)
{
	assert(_render_handle.type == ResourceHandle::NotInitialized && "Trying to reset already initliaized drawable render handle.");
	_render_handle = handle;
}

void Drawable::set_rotation(float rotation)
{
	_rotation = rotation;
	_render_state_changed = true;
}

void Drawable::set_shader(ResourceHandle shader)
{
	_shader = shader;
	_render_state_changed = true;
}

ResourceHandle Drawable::shader() const
{
	return _shader;
}

bool Drawable::state_changed() const
{
	return _render_state_changed;
}

}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: ChartOOoTContext.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: rt $ $Date: 2004-07-13 08:44:28 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, 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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _XMLOFF_CHARTOOOTCONTEXT_HXX
#define _XMLOFF_CHARTOOOTCONTEXT_HXX

#ifndef _XMLOFF_TRANSFORMERCONTEXT_HXX
#include "TransformerContext.hxx"
#endif

class XMLChartOOoTransformerContext : public XMLTransformerContext
{
public:
    TYPEINFO();

    XMLChartOOoTransformerContext( XMLTransformerBase& rTransformer,
                           const ::rtl::OUString& rQName    );
    virtual ~XMLChartOOoTransformerContext();

    virtual void StartElement( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList );
};

#endif  //  _XMLOFF_CHARTOOOTCONTEXT_HXX

<commit_msg>INTEGRATION: CWS ooo19126 (1.2.298); FILE MERGED 2005/09/05 14:40:17 rt 1.2.298.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: ChartOOoTContext.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 15:36:32 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, 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
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _XMLOFF_CHARTOOOTCONTEXT_HXX
#define _XMLOFF_CHARTOOOTCONTEXT_HXX

#ifndef _XMLOFF_TRANSFORMERCONTEXT_HXX
#include "TransformerContext.hxx"
#endif

class XMLChartOOoTransformerContext : public XMLTransformerContext
{
public:
    TYPEINFO();

    XMLChartOOoTransformerContext( XMLTransformerBase& rTransformer,
                           const ::rtl::OUString& rQName    );
    virtual ~XMLChartOOoTransformerContext();

    virtual void StartElement( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList );
};

#endif  //  _XMLOFF_CHARTOOOTCONTEXT_HXX

<|endoftext|>


<commit_before><commit_msg>ISO C++11 does not allow conversion from string literal to 'char *'<commit_after><|endoftext|>


<commit_before>// Copyright 2015-2020 Elviss Strazdins. All rights reserved.

#ifndef OUZEL_STORAGE_ARCHIVE_HPP
#define OUZEL_STORAGE_ARCHIVE_HPP

#include <cstdint>
#include <fstream>
#include <map>
#include <stdexcept>
#include <string>
#include <vector>
#include "../utils/Utils.hpp"

namespace ouzel
{
    namespace storage
    {
        class Archive final
        {
        public:
            Archive() = default;

            explicit Archive(const std::string& path):
                file{path, std::ios::binary}
            {
                constexpr std::uint32_t CENTRAL_DIRECTORY = 0x02014B50;
                constexpr std::uint32_t HEADER_SIGNATURE = 0x04034B50;

                for (;;)
                {
                    std::uint8_t signatureData[4];
                    file.read(reinterpret_cast<char*>(signatureData), sizeof(signatureData));

                    if (decodeLittleEndian<std::uint32_t>(signatureData) == CENTRAL_DIRECTORY)
                        break;

                    if (decodeLittleEndian<std::uint32_t>(signatureData) != HEADER_SIGNATURE)
                        throw std::runtime_error("Bad signature");

                    file.seekg(2, std::ios::cur); // skip version
                    file.seekg(2, std::ios::cur); // skip flags

                    std::uint8_t compressionData[2];
                    file.read(reinterpret_cast<char*>(&compressionData), sizeof(compressionData));

                    if (decodeLittleEndian<std::uint16_t>(compressionData) != 0x00)
                        throw std::runtime_error("Unsupported compression");

                    file.seekg(2, std::ios::cur); // skip modification time
                    file.seekg(2, std::ios::cur); // skip modification date
                    file.seekg(4, std::ios::cur); // skip CRC-32

                    std::uint8_t compressedSizeData[4];
                    file.read(reinterpret_cast<char*>(compressedSizeData), sizeof(compressedSizeData));

                    std::uint8_t uncompressedSizeData[4];
                    file.read(reinterpret_cast<char*>(uncompressedSizeData), sizeof(uncompressedSizeData));
                    const size_t uncompressedSize = decodeLittleEndian<std::uint32_t>(uncompressedSizeData);

                    std::uint8_t fileNameLengthData[2];
                    file.read(reinterpret_cast<char*>(fileNameLengthData), sizeof(fileNameLengthData));
                    const size_t fileNameLength = decodeLittleEndian<std::uint16_t>(fileNameLengthData);

                    std::uint8_t extraFieldLengthData[2];
                    file.read(reinterpret_cast<char*>(extraFieldLengthData), sizeof(extraFieldLengthData));
                    const size_t extraFieldLength = decodeLittleEndian<std::uint16_t>(extraFieldLengthData);

                    auto name = std::make_unique<char[]>(fileNameLength + 1);

                    file.read(name.get(), static_cast<std::streamsize>(fileNameLength));

                    name[fileNameLength] = '\0';

                    Entry& entry = entries[name.get()];
                    entry.size = uncompressedSize;

                    file.seekg(static_cast<std::streamoff>(extraFieldLength),
                               std::ios::cur); // skip extra field

                    entry.offset = file.tellg();

                    file.seekg(static_cast<std::streamoff>(uncompressedSize),
                               std::ios::cur); // skip uncompressed size
                }
            }

            std::vector<std::uint8_t> readFile(const std::string& filename)
            {
                std::vector<std::uint8_t> data;

                auto i = entries.find(filename);

                if (i == entries.end())
                    throw std::runtime_error("File " + filename + " does not exist");

                file.seekg(i->second.offset, std::ios::beg);

                data.resize(i->second.size);

                file.read(reinterpret_cast<char*>(data.data()), static_cast<std::streamsize>(i->second.size));

                return data;
            }

            bool fileExists(const std::string& filename) const
            {
                return entries.find(filename) != entries.end();
            }

        private:
            std::ifstream file;

            struct Entry final
            {
                std::streamoff offset;
                std::size_t size;
            };

            std::map<std::string, Entry> entries;
        };
    } // namespace storage
} // namespace ouzel

#endif // OUZEL_STORAGE_ARCHIVE_HPP
<commit_msg>Initialize data with correct size instead of resizing it<commit_after>// Copyright 2015-2020 Elviss Strazdins. All rights reserved.

#ifndef OUZEL_STORAGE_ARCHIVE_HPP
#define OUZEL_STORAGE_ARCHIVE_HPP

#include <cstdint>
#include <fstream>
#include <map>
#include <stdexcept>
#include <string>
#include <vector>
#include "../utils/Utils.hpp"

namespace ouzel
{
    namespace storage
    {
        class Archive final
        {
        public:
            Archive() = default;

            explicit Archive(const std::string& path):
                file{path, std::ios::binary}
            {
                constexpr std::uint32_t CENTRAL_DIRECTORY = 0x02014B50;
                constexpr std::uint32_t HEADER_SIGNATURE = 0x04034B50;

                for (;;)
                {
                    std::uint8_t signatureData[4];
                    file.read(reinterpret_cast<char*>(signatureData), sizeof(signatureData));

                    if (decodeLittleEndian<std::uint32_t>(signatureData) == CENTRAL_DIRECTORY)
                        break;

                    if (decodeLittleEndian<std::uint32_t>(signatureData) != HEADER_SIGNATURE)
                        throw std::runtime_error("Bad signature");

                    file.seekg(2, std::ios::cur); // skip version
                    file.seekg(2, std::ios::cur); // skip flags

                    std::uint8_t compressionData[2];
                    file.read(reinterpret_cast<char*>(&compressionData), sizeof(compressionData));

                    if (decodeLittleEndian<std::uint16_t>(compressionData) != 0x00)
                        throw std::runtime_error("Unsupported compression");

                    file.seekg(2, std::ios::cur); // skip modification time
                    file.seekg(2, std::ios::cur); // skip modification date
                    file.seekg(4, std::ios::cur); // skip CRC-32

                    std::uint8_t compressedSizeData[4];
                    file.read(reinterpret_cast<char*>(compressedSizeData), sizeof(compressedSizeData));

                    std::uint8_t uncompressedSizeData[4];
                    file.read(reinterpret_cast<char*>(uncompressedSizeData), sizeof(uncompressedSizeData));
                    const size_t uncompressedSize = decodeLittleEndian<std::uint32_t>(uncompressedSizeData);

                    std::uint8_t fileNameLengthData[2];
                    file.read(reinterpret_cast<char*>(fileNameLengthData), sizeof(fileNameLengthData));
                    const size_t fileNameLength = decodeLittleEndian<std::uint16_t>(fileNameLengthData);

                    std::uint8_t extraFieldLengthData[2];
                    file.read(reinterpret_cast<char*>(extraFieldLengthData), sizeof(extraFieldLengthData));
                    const size_t extraFieldLength = decodeLittleEndian<std::uint16_t>(extraFieldLengthData);

                    auto name = std::make_unique<char[]>(fileNameLength + 1);

                    file.read(name.get(), static_cast<std::streamsize>(fileNameLength));

                    name[fileNameLength] = '\0';

                    Entry& entry = entries[name.get()];
                    entry.size = uncompressedSize;

                    file.seekg(static_cast<std::streamoff>(extraFieldLength),
                               std::ios::cur); // skip extra field

                    entry.offset = file.tellg();

                    file.seekg(static_cast<std::streamoff>(uncompressedSize),
                               std::ios::cur); // skip uncompressed size
                }
            }

            std::vector<std::uint8_t> readFile(const std::string& filename)
            {
                auto i = entries.find(filename);

                if (i == entries.end())
                    throw std::runtime_error("File " + filename + " does not exist");

                file.seekg(i->second.offset, std::ios::beg);

                std::vector<std::uint8_t> data(i->second.size);
                file.read(reinterpret_cast<char*>(data.data()), static_cast<std::streamsize>(i->second.size));

                return data;
            }

            bool fileExists(const std::string& filename) const
            {
                return entries.find(filename) != entries.end();
            }

        private:
            std::ifstream file;

            struct Entry final
            {
                std::streamoff offset;
                std::size_t size;
            };

            std::map<std::string, Entry> entries;
        };
    } // namespace storage
} // namespace ouzel

#endif // OUZEL_STORAGE_ARCHIVE_HPP
<|endoftext|>


<commit_before>#include "was/was_server.hxx"
#include "direct.hxx"
#include "pool.hxx"
#include "fb_pool.hxx"

#include <daemon/log.h>

#include <stdio.h>
#include <stdlib.h>
#include <event.h>

struct instance {
    WasServer *server;
};

static void
mirror_request(struct pool *pool, http_method_t method, const char *uri,
               struct strmap *headers, Istream *body, void *ctx)
{
    struct instance *instance = (struct instance *)ctx;

    (void)pool;
    (void)method;
    (void)uri;

    was_server_response(instance->server, HTTP_STATUS_OK, headers, body);
}

static void
mirror_free(void *ctx)
{
    (void)ctx;
}

static constexpr WasServerHandler handler = {
    .request = mirror_request,
    .free = mirror_free,
};

int main(int argc, char **argv) {
    (void)argc;
    (void)argv;

    daemon_log_config.verbose = 5;

    int in_fd = 0, out_fd = 1, control_fd = 3;

    direct_global_init();
    fb_pool_init(false);
    struct event_base *event_base = event_init();

    struct pool *pool = pool_new_libc(nullptr, "root");

    struct instance instance;
    instance.server = was_server_new(pool, control_fd, in_fd, out_fd,
                                     &handler, &instance);

    event_dispatch();

    was_server_free(instance.server);

    pool_unref(pool);
    pool_commit();
    pool_recycler_clear();

    event_base_free(event_base);
    fb_pool_deinit();
    direct_global_deinit();
}
<commit_msg>test/was_mirror: rename struct instance to upper case<commit_after>#include "was/was_server.hxx"
#include "direct.hxx"
#include "pool.hxx"
#include "fb_pool.hxx"

#include <daemon/log.h>

#include <stdio.h>
#include <stdlib.h>
#include <event.h>

struct Instance {
    WasServer *server;
};

static void
mirror_request(struct pool *pool, http_method_t method, const char *uri,
               struct strmap *headers, Istream *body, void *ctx)
{
    auto *instance = (Instance *)ctx;

    (void)pool;
    (void)method;
    (void)uri;

    was_server_response(instance->server, HTTP_STATUS_OK, headers, body);
}

static void
mirror_free(void *ctx)
{
    (void)ctx;
}

static constexpr WasServerHandler handler = {
    .request = mirror_request,
    .free = mirror_free,
};

int main(int argc, char **argv) {
    (void)argc;
    (void)argv;

    daemon_log_config.verbose = 5;

    int in_fd = 0, out_fd = 1, control_fd = 3;

    direct_global_init();
    fb_pool_init(false);
    struct event_base *event_base = event_init();

    struct pool *pool = pool_new_libc(nullptr, "root");

    Instance instance;
    instance.server = was_server_new(pool, control_fd, in_fd, out_fd,
                                     &handler, &instance);

    event_dispatch();

    was_server_free(instance.server);

    pool_unref(pool);
    pool_commit();
    pool_recycler_clear();

    event_base_free(event_base);
    fb_pool_deinit();
    direct_global_deinit();
}
<|endoftext|>