<commit_before>#include "ThermalContactMaterialsAction.h"

#include "ThermalContactAuxVarsAction.h"

#include "Factory.h"

static unsigned int n = 0;

template<>
InputParameters validParams<ThermalContactMaterialsAction>()
{
  MooseEnum orders("CONSTANT, FIRST, SECOND, THIRD, FOURTH", "FIRST");

  InputParameters params = validParams<Action>();
  params.addParam<std::string>("appended_property_name", "", "Name appended to material properties to make them unique");
  params.addRequiredParam<std::string>("type", "A string representing the Moose object that will be used for heat conduction over the gap");
  params.addRequiredParam<NonlinearVariableName>("variable", "The variable for thermal contact");
  params.addRequiredParam<BoundaryName>("master", "The master surface");
  params.addRequiredParam<BoundaryName>("slave", "The slave surface");
  params.addParam<Real>("gap_conductivity", 1.0, "The thermal conductivity of the gap material");
  params.addParam<MooseEnum>("order", orders, "The finite element order");
  params.addParam<bool>("warnings", false, "Whether to output warning messages concerning nodes not being found");
  params.addParam<bool>("quadrature", false, "Whether or not to use quadrature point based gap heat transfer");
  params.addParam<VariableName>("contact_pressure", "The contact pressure variable");
  return params;
}

ThermalContactMaterialsAction::ThermalContactMaterialsAction( const std::string & name, InputParameters params ) :
  Action(name, params)
{
}

void
ThermalContactMaterialsAction::act()
{
  bool quadrature = getParam<bool>("quadrature");

  std::string type("GapConductance");
  if (getParam<std::string>("type") == "GapHeatTransferLWR")
  {
    type += "LWR";
  }

  InputParameters params = _factory.getValidParams(type);
  // Extract global params
  _app.parser().extractParams(_name, params);

  params.print();

  params.set<std::vector<VariableName> >("variable") = std::vector<VariableName>(1, getParam<NonlinearVariableName>("variable"));

  if(!quadrature)
  {
    params.set<std::vector<AuxVariableName> >("gap_temp") = std::vector<AuxVariableName>(1, ThermalContactAuxVarsAction::getGapValueName(_pars));
    std::vector<AuxVariableName> vars(1);
    vars[0] = "penetration";
    params.set<std::vector<AuxVariableName> >("gap_distance") = vars;
  }
  else
  {
    std::vector<VariableName> vars(1);
    vars[0] = getParam<NonlinearVariableName>("variable");
    params.set<std::vector<VariableName> >("temp") = vars;
    params.set<bool>("quadrature") = true;

    params.set<BoundaryName>("paired_boundary") = getParam<BoundaryName>("master");

    params.set<MooseEnum>("order") = getParam<MooseEnum>("order");
  }

  params.set<bool>("warnings") = getParam<bool>("warnings");

  params.set<Real>("gap_conductivity") = getParam<Real>("gap_conductivity");

  std::vector<BoundaryName> bnds(1, getParam<BoundaryName>("slave"));
  params.set<std::vector<BoundaryName> >("boundary") = bnds;

  params.set<std::string>("appended_property_name") = getParam<std::string>("appended_property_name");

  if (getParam<std::string>("type") == "GapHeatTransferLWR")
  {
    std::vector<VariableName> v(1, ThermalContactAuxVarsAction::getGapConductivityName(_pars));
    params.set<std::vector<VariableName> >("gap_k") = v;
    if (isParamValid("contact_pressure"))
    {
      v[0] = getParam<VariableName>("contact_pressure");
      params.set<std::vector<VariableName> >("contact_pressure") = v;
    }
  }

  _problem->addMaterial(type,
    "gap_value_" + Moose::stringify(n),
    params);

  if (quadrature)
  {
    params.set<BoundaryName>("paired_boundary") = getParam<BoundaryName>("slave");

    std::vector<BoundaryName> bnds(1, getParam<BoundaryName>("master"));
    params.set<std::vector<BoundaryName> >("boundary") = bnds;
    if (getParam<std::string>("type") == "GapHeatTransferLWR")
    {
      params.set<bool>("slave_side") = false;
    }
    _problem->addMaterial(type,
      "gap_value_master_" + Moose::stringify(n),
      params);
  }

  ++n;
}
<commit_msg>Remove debugging statement<commit_after>#include "ThermalContactMaterialsAction.h"

#include "ThermalContactAuxVarsAction.h"

#include "Factory.h"

static unsigned int n = 0;

template<>
InputParameters validParams<ThermalContactMaterialsAction>()
{
  MooseEnum orders("CONSTANT, FIRST, SECOND, THIRD, FOURTH", "FIRST");

  InputParameters params = validParams<Action>();
  params.addParam<std::string>("appended_property_name", "", "Name appended to material properties to make them unique");
  params.addRequiredParam<std::string>("type", "A string representing the Moose object that will be used for heat conduction over the gap");
  params.addRequiredParam<NonlinearVariableName>("variable", "The variable for thermal contact");
  params.addRequiredParam<BoundaryName>("master", "The master surface");
  params.addRequiredParam<BoundaryName>("slave", "The slave surface");
  params.addParam<Real>("gap_conductivity", 1.0, "The thermal conductivity of the gap material");
  params.addParam<MooseEnum>("order", orders, "The finite element order");
  params.addParam<bool>("warnings", false, "Whether to output warning messages concerning nodes not being found");
  params.addParam<bool>("quadrature", false, "Whether or not to use quadrature point based gap heat transfer");
  params.addParam<VariableName>("contact_pressure", "The contact pressure variable");
  return params;
}

ThermalContactMaterialsAction::ThermalContactMaterialsAction( const std::string & name, InputParameters params ) :
  Action(name, params)
{
}

void
ThermalContactMaterialsAction::act()
{
  bool quadrature = getParam<bool>("quadrature");

  std::string type("GapConductance");
  if (getParam<std::string>("type") == "GapHeatTransferLWR")
  {
    type += "LWR";
  }

  InputParameters params = _factory.getValidParams(type);
  // Extract global params
  _app.parser().extractParams(_name, params);

  params.set<std::vector<VariableName> >("variable") = std::vector<VariableName>(1, getParam<NonlinearVariableName>("variable"));

  if(!quadrature)
  {
    params.set<std::vector<AuxVariableName> >("gap_temp") = std::vector<AuxVariableName>(1, ThermalContactAuxVarsAction::getGapValueName(_pars));
    std::vector<AuxVariableName> vars(1);
    vars[0] = "penetration";
    params.set<std::vector<AuxVariableName> >("gap_distance") = vars;
  }
  else
  {
    std::vector<VariableName> vars(1);
    vars[0] = getParam<NonlinearVariableName>("variable");
    params.set<std::vector<VariableName> >("temp") = vars;
    params.set<bool>("quadrature") = true;

    params.set<BoundaryName>("paired_boundary") = getParam<BoundaryName>("master");

    params.set<MooseEnum>("order") = getParam<MooseEnum>("order");
  }

  params.set<bool>("warnings") = getParam<bool>("warnings");

  params.set<Real>("gap_conductivity") = getParam<Real>("gap_conductivity");

  std::vector<BoundaryName> bnds(1, getParam<BoundaryName>("slave"));
  params.set<std::vector<BoundaryName> >("boundary") = bnds;

  params.set<std::string>("appended_property_name") = getParam<std::string>("appended_property_name");

  if (getParam<std::string>("type") == "GapHeatTransferLWR")
  {
    std::vector<VariableName> v(1, ThermalContactAuxVarsAction::getGapConductivityName(_pars));
    params.set<std::vector<VariableName> >("gap_k") = v;
    if (isParamValid("contact_pressure"))
    {
      v[0] = getParam<VariableName>("contact_pressure");
      params.set<std::vector<VariableName> >("contact_pressure") = v;
    }
  }

  _problem->addMaterial(type,
    "gap_value_" + Moose::stringify(n),
    params);

  if (quadrature)
  {
    params.set<BoundaryName>("paired_boundary") = getParam<BoundaryName>("slave");

    std::vector<BoundaryName> bnds(1, getParam<BoundaryName>("master"));
    params.set<std::vector<BoundaryName> >("boundary") = bnds;
    if (getParam<std::string>("type") == "GapHeatTransferLWR")
    {
      params.set<bool>("slave_side") = false;
    }
    _problem->addMaterial(type,
      "gap_value_master_" + Moose::stringify(n),
      params);
  }

  ++n;
}
<|endoftext|>


<commit_before>#include "terrainedit.h"
#include "terrain.h"
#include <QRect>

inline uint qHash(const QPoint &key, uint seed)
{
    return qHash(key.x(), seed) ^ (qHash(key.y(), seed) >> 8 | qHash(~key.y(), seed) << 24);
}

TerrainEdit::TerrainEdit(QObject *parent) :
    QObject(parent),
    done_(false)
{

}

TerrainEdit::~TerrainEdit()
{

}

void TerrainEdit::beginEdit(const QRect &r, Terrain *t)
{
    Q_ASSERT(!done_);
    Q_ASSERT(t);
    Q_ASSERT(r.isValid());
    Q_ASSERT(r.left() >= 0); Q_ASSERT(r.top() >= 0);
    Q_ASSERT(r.x() + r.width() <= t->size().width());
    Q_ASSERT(r.y() + r.height() <= t->size().height());

    int x1 = r.x() >> SubeditSizeBits;
    int y1 = r.y() >> SubeditSizeBits;
    int x2 = (r.x() + r.width() + SubeditSize - 1) >> SubeditSizeBits;
    int y2 = (r.y() + r.height() + SubeditSize - 1) >> SubeditSizeBits;
    for (int x = x1; x < x2; ++x) {
        for (int y = y1; y < y2; ++y) {
            QPoint block(x, y);
            TerrainSubedit &subedit = subedits_[block];
            if (!subedit.before) {
                // initialize subedit
                subedit.position = QPoint(x << SubeditSizeBits, y << SubeditSizeBits);
                subedit.before = std::make_shared<Terrain>(QSize(SubeditSize, SubeditSize));
                subedit.after = std::make_shared<Terrain>(QSize(SubeditSize, SubeditSize));
                subedit.before->copyFrom(t, QPoint(0, 0), QRect(subedit.position, QSize(SubeditSize, SubeditSize)));
                subedit.editing = false;
            }
            subedit.editing = true;
        }
    }
}

void TerrainEdit::endEdit(Terrain *t)
{
    Q_ASSERT(!done_);
    Q_ASSERT(t);

    QRect rt;
    for (TerrainSubedit& e: subedits_) {
        if (e.editing) {
            if (rt.isEmpty()) {
                rt = QRect(e.position.x(), e.position.y(), SubeditSize, SubeditSize);
            } else {
                rt = rt.united(QRect(e.position.x(), e.position.y(), SubeditSize, SubeditSize));
            }
            e.after->copyFrom(t, QPoint(0, 0), QRect(e.position.x(), e.position.y(), SubeditSize, SubeditSize));
            e.editing = false;
        }
    }

    if (!rt.isEmpty()) {
        emit edited(rt);
    }
}

void TerrainEdit::done()
{
    done_ = true;
}

void TerrainEdit::apply(Terrain *t)
{
    Q_ASSERT(t);
    for (TerrainSubedit& e: subedits_) {
        t->copyFrom(e.after.get(), e.position);
    }
}

void TerrainEdit::undo(Terrain *t)
{
    Q_ASSERT(t);
    for (TerrainSubedit& e: subedits_) {
        t->copyFrom(e.before.get(), e.position);
    }
}

QRect TerrainEdit::modifiedBounds()
{
    QRect rt;
    for (TerrainSubedit& e: subedits_) {
        if (rt.isEmpty()) {
            rt = QRect(e.position.x(), e.position.y(), SubeditSize, SubeditSize);
        } else {
            rt = rt.united(QRect(e.position.x(), e.position.y(), SubeditSize, SubeditSize));
        }
    }
    return rt;
}

void TerrainEdit::copyBeforeTo(const QRect &srcRect, Terrain *after, Terrain *copyTo)
{
    Q_ASSERT(after);
    Q_ASSERT(copyTo);

    QRect r = srcRect;
    Q_ASSERT(r.x() >= 0); Q_ASSERT(r.y() >= 0);
    Q_ASSERT(r.x() + r.width() < after->size().width());
    Q_ASSERT(r.y() + r.height() < after->size().height());

    // TODO: clip copy destination size by srcRect

    int x1 = r.x() >> SubeditSizeBits;
    int y1 = r.y() >> SubeditSizeBits;
    int x2 = (r.x() + r.width() + SubeditSize - 1) >> SubeditSizeBits;
    int y2 = (r.y() + r.height() + SubeditSize - 1) >> SubeditSizeBits;

    for (int x = x1; x < x2; ++x) {
        for (int y = y1; y < y2; ++y) {
            QPoint block(x, y);
            auto it = subedits_.find(block);
            if (it == subedits_.end()) {
                // unmodified
                copyTo->copyFrom(after, QPoint((x << SubeditSizeBits) - srcRect.x(), (y << SubeditSizeBits) - srcRect.y()),
                                 QRect(x << SubeditSizeBits, y << SubeditSizeBits,
                                       SubeditSize, SubeditSize));
            } else {
                // modified
                TerrainSubedit &subedit = *it;
                copyTo->copyFrom(subedit.before.get(),
                                 QPoint((x << SubeditSizeBits) - srcRect.x(), (y << SubeditSizeBits) - srcRect.y()));
            }
        }
    }

}

uint TerrainEdit::size() const
{
    return subedits_.size() * SubeditSize * SubeditSize * 8;
}
<commit_msg>Fix asserts<commit_after>#include "terrainedit.h"
#include "terrain.h"
#include <QRect>

inline uint qHash(const QPoint &key, uint seed)
{
    return qHash(key.x(), seed) ^ (qHash(key.y(), seed) >> 8 | qHash(~key.y(), seed) << 24);
}

TerrainEdit::TerrainEdit(QObject *parent) :
    QObject(parent),
    done_(false)
{

}

TerrainEdit::~TerrainEdit()
{

}

void TerrainEdit::beginEdit(const QRect &r, Terrain *t)
{
    Q_ASSERT(!done_);
    Q_ASSERT(t);
    if (r.isEmpty()) {
        return;
    }
    Q_ASSERT(r.left() >= 0); Q_ASSERT(r.top() >= 0);
    Q_ASSERT(r.x() + r.width() <= t->size().width());
    Q_ASSERT(r.y() + r.height() <= t->size().height());

    int x1 = r.x() >> SubeditSizeBits;
    int y1 = r.y() >> SubeditSizeBits;
    int x2 = (r.x() + r.width() + SubeditSize - 1) >> SubeditSizeBits;
    int y2 = (r.y() + r.height() + SubeditSize - 1) >> SubeditSizeBits;
    for (int x = x1; x < x2; ++x) {
        for (int y = y1; y < y2; ++y) {
            QPoint block(x, y);
            TerrainSubedit &subedit = subedits_[block];
            if (!subedit.before) {
                // initialize subedit
                subedit.position = QPoint(x << SubeditSizeBits, y << SubeditSizeBits);
                subedit.before = std::make_shared<Terrain>(QSize(SubeditSize, SubeditSize));
                subedit.after = std::make_shared<Terrain>(QSize(SubeditSize, SubeditSize));
                subedit.before->copyFrom(t, QPoint(0, 0), QRect(subedit.position, QSize(SubeditSize, SubeditSize)));
                subedit.editing = false;
            }
            subedit.editing = true;
        }
    }
}

void TerrainEdit::endEdit(Terrain *t)
{
    Q_ASSERT(!done_);
    Q_ASSERT(t);

    QRect rt;
    for (TerrainSubedit& e: subedits_) {
        if (e.editing) {
            if (rt.isEmpty()) {
                rt = QRect(e.position.x(), e.position.y(), SubeditSize, SubeditSize);
            } else {
                rt = rt.united(QRect(e.position.x(), e.position.y(), SubeditSize, SubeditSize));
            }
            e.after->copyFrom(t, QPoint(0, 0), QRect(e.position.x(), e.position.y(), SubeditSize, SubeditSize));
            e.editing = false;
        }
    }

    if (!rt.isEmpty()) {
        emit edited(rt);
    }
}

void TerrainEdit::done()
{
    done_ = true;
}

void TerrainEdit::apply(Terrain *t)
{
    Q_ASSERT(t);
    for (TerrainSubedit& e: subedits_) {
        t->copyFrom(e.after.get(), e.position);
    }
}

void TerrainEdit::undo(Terrain *t)
{
    Q_ASSERT(t);
    for (TerrainSubedit& e: subedits_) {
        t->copyFrom(e.before.get(), e.position);
    }
}

QRect TerrainEdit::modifiedBounds()
{
    QRect rt;
    for (TerrainSubedit& e: subedits_) {
        if (rt.isEmpty()) {
            rt = QRect(e.position.x(), e.position.y(), SubeditSize, SubeditSize);
        } else {
            rt = rt.united(QRect(e.position.x(), e.position.y(), SubeditSize, SubeditSize));
        }
    }
    return rt;
}

void TerrainEdit::copyBeforeTo(const QRect &srcRect, Terrain *after, Terrain *copyTo)
{
    Q_ASSERT(after);
    Q_ASSERT(copyTo);

    QRect r = srcRect;
    Q_ASSERT(r.x() >= 0); Q_ASSERT(r.y() >= 0);
    Q_ASSERT(r.x() + r.width() <= after->size().width());
    Q_ASSERT(r.y() + r.height() <= after->size().height());

    // TODO: clip copy destination size by srcRect

    int x1 = r.x() >> SubeditSizeBits;
    int y1 = r.y() >> SubeditSizeBits;
    int x2 = (r.x() + r.width() + SubeditSize - 1) >> SubeditSizeBits;
    int y2 = (r.y() + r.height() + SubeditSize - 1) >> SubeditSizeBits;

    for (int x = x1; x < x2; ++x) {
        for (int y = y1; y < y2; ++y) {
            QPoint block(x, y);
            auto it = subedits_.find(block);
            if (it == subedits_.end()) {
                // unmodified
                copyTo->copyFrom(after, QPoint((x << SubeditSizeBits) - srcRect.x(), (y << SubeditSizeBits) - srcRect.y()),
                                 QRect(x << SubeditSizeBits, y << SubeditSizeBits,
                                       SubeditSize, SubeditSize));
            } else {
                // modified
                TerrainSubedit &subedit = *it;
                copyTo->copyFrom(subedit.before.get(),
                                 QPoint((x << SubeditSizeBits) - srcRect.x(), (y << SubeditSizeBits) - srcRect.y()));
            }
        }
    }

}

uint TerrainEdit::size() const
{
    return subedits_.size() * SubeditSize * SubeditSize * 8;
}
<|endoftext|>


<commit_before>// set of classes to compare the performance of STL vector versus
// native Root TClonesArray.
// See main program bench.cxx

#include "TRandom.h"
#include "TFile.h"
#include "TTree.h"
#include "TClass.h"
//the next include must be the last one on systems like Windows/NT
#include "TBench.h"

THit hit;
const char *demofile = "$TEMP/bench.root";

//-------------------------------------------------------------
ClassImp(THit)
//-------------------------------------------------------------
THit::THit() {
  fPulses = 0;
}
THit::THit(const THit &hit) {
  fX = hit.fX;
  fY = hit.fY;
  fZ = hit.fZ;
  for (Int_t i=0;i<10;i++) fTime[i] = hit.fTime[i];
  fPulses = 0;
  fNpulses = hit.fNpulses;
  if (fNpulses == 0) return;
  if (hit.fPulses == 0) return;
  fPulses = new int[fNpulses];
  for (int j=0;j<fNpulses;j++) fPulses[j] = hit.fPulses[j];
}

THit::THit(int t) {
  fPulses = 0;
  Set(t);
}

THit::~THit() {
   if (fPulses) delete [] fPulses;
   fPulses = 0;
}

void THit::Set(int t) {
  fX = gRandom->Gaus(0,1);
  fY = gRandom->Gaus(0,1);
  fZ = gRandom->Gaus(0,10);
  if (fPulses && fNpulses > 0) delete [] fPulses;
  fNpulses = t%20 + 1;
  fPulses = new int[fNpulses];
  for (int j=0;j<fNpulses;j++) fPulses[j] = j+1;
  for (int i=0; i<10; i++) fTime[i] = t+i;
}

#if 0
#if defined(R__TEMPLATE_OVERLOAD_BUG)
template <>
#endif
TBuffer &operator>>(TBuffer &buf, THit *&obj)
{
   obj = new THit();
   obj->Streamer(buf);
   return buf;
}
#endif

TBuffer &operator<<(TBuffer &buf, const THit *obj)
{
   ((THit*)obj)->Streamer(buf);
   return buf;
}

//-------------------------------------------------------------
ClassImp(TObjHit)
//-------------------------------------------------------------

TObjHit::TObjHit() :THit() {}
TObjHit::TObjHit(int t) :THit(t) {}

//-------------------------------------------------------------
ClassImp(TSTLhit)
//-------------------------------------------------------------
TSTLhit::TSTLhit()
{
}

TSTLhit::TSTLhit(Int_t nmax)
{
   fNhits = nmax;
   fList1.reserve(nmax);
}

TSTLhit::~TSTLhit() {
}

void TSTLhit::Clear(Option_t *)
{
   fList1.erase(fList1.begin(),fList1.end());
}

void TSTLhit::MakeEvent(int ievent)
{
   Clear();
   for (Int_t j=0; j<fNhits; j++) {
      hit.Set(j);
      fList1.push_back(hit);
   }
}

Int_t TSTLhit::MakeTree(int mode, int nevents, int compression, int split, float &cx)
{
  TFile *f=0;
  TTree *T=0;
  TSTLhit *top = this;
  if (mode > 0) {
     f = new TFile(demofile,"recreate","STLhit",compression);
     T = new TTree("T","Demo tree");
     T->Branch("event","TSTLhit",&top,64000,split);
  }
  for (int ievent=0; ievent<nevents; ievent++) {
     MakeEvent(ievent);
     if (mode > 0) T->Fill();
  }

  if (mode == 0) return 0;
  T->Write();
  delete f;
  f = new TFile(demofile);
  Int_t nbytes = f->GetEND();
  cx = f->GetCompressionFactor();
  delete f;
  return nbytes;
}

Int_t TSTLhit::ReadTree()
{
  TSTLhit *top = this;
  TFile *f = new TFile(demofile);
  TTree *T = (TTree*)f->Get("T");
  T->SetBranchAddress("event",&top);
  Int_t nevents = (Int_t)T->GetEntries();
  Int_t nbytes = 0;
  for (int ievent=0; ievent<nevents; ievent++) {
     nbytes += T->GetEntry(ievent);
     Clear();
  }
  delete f;
  return nbytes;
}

//-------------------------------------------------------------
ClassImp(TSTLhitStar)
//-------------------------------------------------------------
TSTLhitStar::TSTLhitStar()
{
}

TSTLhitStar::TSTLhitStar(Int_t nmax)
{
   fNhits = nmax;
   fList2.reserve(nmax);
}

TSTLhitStar::~TSTLhitStar() {
}

void TSTLhitStar::Clear(Option_t *)
{
   for (vector<THit*>::iterator it = fList2.begin(); it<fList2.end(); it++) {
      delete (*it);
   }
   fList2.erase(fList2.begin(),fList2.end());
}

void TSTLhitStar::MakeEvent(int ievent)
{
   Clear();
   for (Int_t j=0; j<fNhits; j++) {
      fList2.push_back(new THit(j));
   }
}

Int_t TSTLhitStar::MakeTree(int mode, int nevents, int compression, int split, float &cx)
{
  TFile *f=0;
  TTree *T=0;
  TSTLhitStar *top = this;
  if (mode > 0) {
     f = new TFile(demofile,"recreate","STLhitStar",compression);
     T = new TTree("T","Demo tree");
     T->Branch("event","TSTLhitStar",&top,64000,split);
  }
  for (int ievent=0; ievent<nevents; ievent++) {
     MakeEvent(ievent);
     if (mode > 0) T->Fill();
  }

  if (mode == 0) return 0;
  T->Write();
  delete f;
  f = new TFile(demofile);
  Int_t nbytes = f->GetEND();
  cx = f->GetCompressionFactor();
  delete f;
  return nbytes;
}

Int_t TSTLhitStar::ReadTree()
{
  TSTLhitStar *top = this;
  TFile *f = new TFile(demofile);
  TTree *T = (TTree*)f->Get("T");
  T->SetBranchAddress("event",&top);
  Int_t nevents = (Int_t)T->GetEntries();
  Int_t nbytes = 0;
  for (int ievent=0; ievent<nevents; ievent++) {
     nbytes += T->GetEntry(ievent);
     Clear();
  }
  delete f;
  return nbytes;
}

//-------------------------------------------------------------
ClassImp(TCloneshit)
//-------------------------------------------------------------
TCloneshit::TCloneshit()
{
   fList3 = new TClonesArray("TObjHit");
}

TCloneshit::TCloneshit(Int_t nmax)
{
   fNhits = nmax;
   fList3 = new TClonesArray("TObjHit",nmax);
   TObjHit::Class()->IgnoreTObjectStreamer();
}

TCloneshit::~TCloneshit() {
}

void TCloneshit::Clear(Option_t *)
{
   fList3->Delete();
   //fList3->Clear();
}

void TCloneshit::MakeEvent(int ievent)
{
   Clear();
   for (Int_t j=0; j<fNhits; j++) {
      new((*fList3)[j]) TObjHit(j);
   }
}

Int_t TCloneshit::MakeTree(int mode, int nevents, int compression, int split, float &cx)
{
  TFile *f=0;
  TTree *T=0;
  TCloneshit *top = this;
  if (mode > 0) {
     f = new TFile(demofile,"recreate","Cloneshit",compression);
     T = new TTree("T","Demo tree");
     T->Branch("event","TCloneshit",&top,64000,split);
  }
  for (int ievent=0; ievent<nevents; ievent++) {
     MakeEvent(ievent);
     if (mode > 0) T->Fill();
  }

  if (mode == 0) return 0;
  T->Write();
  delete f;
  f = new TFile(demofile);
  Int_t nbytes = f->GetEND();
  cx = f->GetCompressionFactor();
  delete f;
  return nbytes;
}

Int_t TCloneshit::ReadTree()
{
  TCloneshit *top = this;
  TFile *f = new TFile(demofile);
  TTree *T = (TTree*)f->Get("T");
  T->SetBranchAddress("event",&top);
  Int_t nevents = (Int_t)T->GetEntries();
  Int_t nbytes = 0;
  for (int ievent=0; ievent<nevents; ievent++) {
     nbytes += T->GetEntry(ievent);
  }
  delete f;
  return nbytes;
}

<commit_msg>Undo Philippe's change in TBench. Use /tmp/bench.root instead of $TEMP.<commit_after>// set of classes to compare the performance of STL vector versus
// native Root TClonesArray.
// See main program bench.cxx

#include "TRandom.h"
#include "TFile.h"
#include "TTree.h"
#include "TClass.h"
//the next include must be the last one on systems like Windows/NT
#include "TBench.h"

THit hit;
const char *demofile = "/tmp/bench.root";

//-------------------------------------------------------------
ClassImp(THit)
//-------------------------------------------------------------
THit::THit() {
  fPulses = 0;
}
THit::THit(const THit &hit) {
  fX = hit.fX;
  fY = hit.fY;
  fZ = hit.fZ;
  for (Int_t i=0;i<10;i++) fTime[i] = hit.fTime[i];
  fPulses = 0;
  fNpulses = hit.fNpulses;
  if (fNpulses == 0) return;
  if (hit.fPulses == 0) return;
  fPulses = new int[fNpulses];
  for (int j=0;j<fNpulses;j++) fPulses[j] = hit.fPulses[j];
}

THit::THit(int t) {
  fPulses = 0;
  Set(t);
}

THit::~THit() {
   if (fPulses) delete [] fPulses;
   fPulses = 0;
}

void THit::Set(int t) {
  fX = gRandom->Gaus(0,1);
  fY = gRandom->Gaus(0,1);
  fZ = gRandom->Gaus(0,10);
  if (fPulses && fNpulses > 0) delete [] fPulses;
  fNpulses = t%20 + 1;
  fPulses = new int[fNpulses];
  for (int j=0;j<fNpulses;j++) fPulses[j] = j+1;
  for (int i=0; i<10; i++) fTime[i] = t+i;
}

#if 0
#if defined(R__TEMPLATE_OVERLOAD_BUG)
template <>
#endif
TBuffer &operator>>(TBuffer &buf, THit *&obj)
{
   obj = new THit();
   obj->Streamer(buf);
   return buf;
}
#endif

TBuffer &operator<<(TBuffer &buf, const THit *obj)
{
   ((THit*)obj)->Streamer(buf);
   return buf;
}

//-------------------------------------------------------------
ClassImp(TObjHit)
//-------------------------------------------------------------

TObjHit::TObjHit() :THit() {}
TObjHit::TObjHit(int t) :THit(t) {}

//-------------------------------------------------------------
ClassImp(TSTLhit)
//-------------------------------------------------------------
TSTLhit::TSTLhit()
{
}

TSTLhit::TSTLhit(Int_t nmax)
{
   fNhits = nmax;
   fList1.reserve(nmax);
}

TSTLhit::~TSTLhit() {
}

void TSTLhit::Clear(Option_t *)
{
   fList1.erase(fList1.begin(),fList1.end());
}

void TSTLhit::MakeEvent(int ievent)
{
   Clear();
   for (Int_t j=0; j<fNhits; j++) {
      hit.Set(j);
      fList1.push_back(hit);
   }
}

Int_t TSTLhit::MakeTree(int mode, int nevents, int compression, int split, float &cx)
{
  TFile *f=0;
  TTree *T=0;
  TSTLhit *top = this;
  if (mode > 0) {
     f = new TFile(demofile,"recreate","STLhit",compression);
     T = new TTree("T","Demo tree");
     T->Branch("event","TSTLhit",&top,64000,split);
  }
  for (int ievent=0; ievent<nevents; ievent++) {
     MakeEvent(ievent);
     if (mode > 0) T->Fill();
  }

  if (mode == 0) return 0;
  T->Write();
  delete f;
  f = new TFile(demofile);
  Int_t nbytes = f->GetEND();
  cx = f->GetCompressionFactor();
  delete f;
  return nbytes;
}

Int_t TSTLhit::ReadTree()
{
  TSTLhit *top = this;
  TFile *f = new TFile(demofile);
  TTree *T = (TTree*)f->Get("T");
  T->SetBranchAddress("event",&top);
  Int_t nevents = (Int_t)T->GetEntries();
  Int_t nbytes = 0;
  for (int ievent=0; ievent<nevents; ievent++) {
     nbytes += T->GetEntry(ievent);
     Clear();
  }
  delete f;
  return nbytes;
}

//-------------------------------------------------------------
ClassImp(TSTLhitStar)
//-------------------------------------------------------------
TSTLhitStar::TSTLhitStar()
{
}

TSTLhitStar::TSTLhitStar(Int_t nmax)
{
   fNhits = nmax;
   fList2.reserve(nmax);
}

TSTLhitStar::~TSTLhitStar() {
}

void TSTLhitStar::Clear(Option_t *)
{
   for (vector<THit*>::iterator it = fList2.begin(); it<fList2.end(); it++) {
      delete (*it);
   }
   fList2.erase(fList2.begin(),fList2.end());
}

void TSTLhitStar::MakeEvent(int ievent)
{
   Clear();
   for (Int_t j=0; j<fNhits; j++) {
      fList2.push_back(new THit(j));
   }
}

Int_t TSTLhitStar::MakeTree(int mode, int nevents, int compression, int split, float &cx)
{
  TFile *f=0;
  TTree *T=0;
  TSTLhitStar *top = this;
  if (mode > 0) {
     f = new TFile(demofile,"recreate","STLhitStar",compression);
     T = new TTree("T","Demo tree");
     T->Branch("event","TSTLhitStar",&top,64000,split);
  }
  for (int ievent=0; ievent<nevents; ievent++) {
     MakeEvent(ievent);
     if (mode > 0) T->Fill();
  }

  if (mode == 0) return 0;
  T->Write();
  delete f;
  f = new TFile(demofile);
  Int_t nbytes = f->GetEND();
  cx = f->GetCompressionFactor();
  delete f;
  return nbytes;
}

Int_t TSTLhitStar::ReadTree()
{
  TSTLhitStar *top = this;
  TFile *f = new TFile(demofile);
  TTree *T = (TTree*)f->Get("T");
  T->SetBranchAddress("event",&top);
  Int_t nevents = (Int_t)T->GetEntries();
  Int_t nbytes = 0;
  for (int ievent=0; ievent<nevents; ievent++) {
     nbytes += T->GetEntry(ievent);
     Clear();
  }
  delete f;
  return nbytes;
}

//-------------------------------------------------------------
ClassImp(TCloneshit)
//-------------------------------------------------------------
TCloneshit::TCloneshit()
{
   fList3 = new TClonesArray("TObjHit");
}

TCloneshit::TCloneshit(Int_t nmax)
{
   fNhits = nmax;
   fList3 = new TClonesArray("TObjHit",nmax);
   TObjHit::Class()->IgnoreTObjectStreamer();
}

TCloneshit::~TCloneshit() {
}

void TCloneshit::Clear(Option_t *)
{
   fList3->Delete();
   //fList3->Clear();
}

void TCloneshit::MakeEvent(int ievent)
{
   Clear();
   for (Int_t j=0; j<fNhits; j++) {
      new((*fList3)[j]) TObjHit(j);
   }
}

Int_t TCloneshit::MakeTree(int mode, int nevents, int compression, int split, float &cx)
{
  TFile *f=0;
  TTree *T=0;
  TCloneshit *top = this;
  if (mode > 0) {
     f = new TFile(demofile,"recreate","Cloneshit",compression);
     T = new TTree("T","Demo tree");
     T->Branch("event","TCloneshit",&top,64000,split);
  }
  for (int ievent=0; ievent<nevents; ievent++) {
     MakeEvent(ievent);
     if (mode > 0) T->Fill();
  }

  if (mode == 0) return 0;
  T->Write();
  delete f;
  f = new TFile(demofile);
  Int_t nbytes = f->GetEND();
  cx = f->GetCompressionFactor();
  delete f;
  return nbytes;
}

Int_t TCloneshit::ReadTree()
{
  TCloneshit *top = this;
  TFile *f = new TFile(demofile);
  TTree *T = (TTree*)f->Get("T");
  T->SetBranchAddress("event",&top);
  Int_t nevents = (Int_t)T->GetEntries();
  Int_t nbytes = 0;
  for (int ievent=0; ievent<nevents; ievent++) {
     nbytes += T->GetEntry(ievent);
  }
  delete f;
  return nbytes;
}

<|endoftext|>


<commit_before>#include <QtCore/QPair>
#include <QtCore/QStack>

#include "generatorBase/masterGeneratorBase.h"

#include <qrutils/outFile.h>
#include <qrutils/stringUtils.h>
#include <qrtext/languageToolboxInterface.h>

#include "readableControlFlowGenerator.h"
#include "gotoControlFlowGenerator.h"
#include "generatorBase/lua/luaProcessor.h"
#include "generatorBase/parts/variables.h"
#include "generatorBase/parts/subprograms.h"
#include "generatorBase/parts/threads.h"
#include "generatorBase/parts/sensors.h"
#include "generatorBase/parts/initTerminateCodeGenerator.h"

using namespace generatorBase;
using namespace qReal;

MasterGeneratorBase::MasterGeneratorBase(const qrRepo::RepoApi &repo
		, ErrorReporterInterface &errorReporter
		, const kitBase::robotModel::RobotModelManagerInterface &robotModelManager
		, qrtext::LanguageToolboxInterface &textLanguage
		, const utils::ParserErrorReporter &parserErrorReporter
		, const Id &diagramId)
	: mRepo(repo)
	, mErrorReporter(errorReporter)
	, mRobotModelManager(robotModelManager)
	, mTextLanguage(textLanguage)
	, mDiagram(diagramId)
	, mParserErrorReporter(parserErrorReporter)
{
}

void MasterGeneratorBase::setProjectDir(const QFileInfo &fileInfo)
{
	mProjectName = fileInfo.baseName();
	mProjectDir = fileInfo.absolutePath();
}

void MasterGeneratorBase::initialize()
{
	mCustomizer = createCustomizer();
	mCustomizer->factory()->initialize();
	setPathToTemplates(mCustomizer->factory()->pathToTemplates());

	mValidator = createValidator();

	mReadableControlFlowGenerator = new ReadableControlFlowGenerator(mRepo
			, mErrorReporter, *mCustomizer, *mValidator, mDiagram, this);
	mGotoControlFlowGenerator = new GotoControlFlowGenerator(mRepo
			, mErrorReporter, *mCustomizer, *mValidator, mDiagram, this);
}

QString MasterGeneratorBase::generate(const QString &indentString)
{
	if (mDiagram.isNull()) {
		mErrorReporter.addCritical(QObject::tr("There is no opened diagram"));
		return QString();
	}

	beforeGeneration();
	if (!QDir(mProjectDir).exists()) {
		QDir().mkpath(mProjectDir);
	}

	mTextLanguage.clear();
	mCustomizer->factory()->setMainDiagramId(mDiagram);

	for (parts::InitTerminateCodeGenerator *generator : mCustomizer->factory()->initTerminateGenerators()) {
		generator->reinit();
	}

	QString mainCode;
	const semantics::SemanticTree *mainControlFlow = mReadableControlFlowGenerator->generate();
	if (mainControlFlow && !mReadableControlFlowGenerator->cantBeGeneratedIntoStructuredCode()) {
		mainCode = mainControlFlow->toString(1, indentString);
		const bool subprogramsResult = mCustomizer->factory()->subprograms()->generate(mReadableControlFlowGenerator
				, indentString);
		if (!subprogramsResult) {
			if (supportsGotoGeneration()) {
				mainCode = QString();
			} else {
				return QString();
			}
		}
	} else {
		if (mReadableControlFlowGenerator->errorsOccured()) {
			return QString();
		}
	}

	if (mainCode.isEmpty() && supportsGotoGeneration()) {
		mErrorReporter.addInformation(tr("This diagram cannot be generated into the structured code."\
				" Generating it into the code with 'goto' statements."));
		const semantics::SemanticTree *gotoMainControlFlow = mGotoControlFlowGenerator->generate();
		if (gotoMainControlFlow) {
			mainCode = gotoMainControlFlow->toString(1, indentString);
			const bool gotoSubprogramsResult = mCustomizer->factory()
					->subprograms()->generate(mGotoControlFlowGenerator, indentString);
			if (!gotoSubprogramsResult) {
				mainCode = QString();
			}
		}
	}

	if (mainCode.isEmpty()) {
		const QString errorMessage = supportsGotoGeneration()
				? tr("This diagram cannot be even generated into the code with 'goto'"\
						"statements. Please contact the developers (WTF did you do?)")
				: tr("This diagram cannot be generated into the structured code.");
		mErrorReporter.addError(errorMessage);
		return QString();
	}

	QString resultCode = readTemplate("main.t");
	resultCode.replace("@@SUBPROGRAMS_FORWARDING@@", mCustomizer->factory()->subprograms()->forwardDeclarations());
	resultCode.replace("@@SUBPROGRAMS@@", mCustomizer->factory()->subprograms()->implementations());
	resultCode.replace("@@THREADS_FORWARDING@@", mCustomizer->factory()->threads().generateDeclarations());
	resultCode.replace("@@THREADS@@", mCustomizer->factory()->threads().generateImplementations(indentString));
	resultCode.replace("@@MAIN_CODE@@", mainCode);
	resultCode.replace("@@INITHOOKS@@", utils::StringUtils::addIndent(
			mCustomizer->factory()->initCode(), 1, indentString));
	resultCode.replace("@@TERMINATEHOOKS@@", utils::StringUtils::addIndent(
			mCustomizer->factory()->terminateCode(), 1, indentString));
	resultCode.replace("@@USERISRHOOKS@@", utils::StringUtils::addIndent(
			mCustomizer->factory()->isrHooksCode(), 1, indentString));
	resultCode.replace("@@VARIABLES@@", mCustomizer->factory()->variables()->generateVariableString());
	// This will remove too many empty lines
	resultCode.replace(QRegExp("\n(\n)+"), "\n\n");

	resultCode = generateLinkingInfo(resultCode);

	processGeneratedCode(resultCode);

	const QString pathToOutput = targetPath();
	outputCode(pathToOutput, resultCode);

	afterGeneration();

	return pathToOutput;
}

QString MasterGeneratorBase::generateLinkingInfo(QString &resultCode)
{
	QString const open = "@~(qrm:(/\\w+)+/\\{(\\w+-)+\\w+\\})~@";
	QString const close = "@#%1#@";
	QRegExp re;
	QStack< QPair<QString, int> > stack;
	QList< QPair<QString, QPair<int, int>> > results;
	int lineNumber = 1;

	for (QString const &line : resultCode.split("\n")){
		re.setPattern(open);
		int const pos = re.indexIn(line);
		if (pos > -1) {
			QString const id = re.cap(1);
			stack.push(QPair<QString, int>(id, lineNumber));
		}

		if (!stack.isEmpty()) {
			QString const id = stack.top().first;
			if (line.contains(close.arg(id))) {
				results.append(QPair<QString, QPair<int, int>>(id
						, QPair<int, int>(stack.top().second, lineNumber)));
				stack.pop();
			}
		}

		lineNumber++;
	}

	QString out;

	for (QPair<QString, QPair<int, int>> res : results) {
		out += res.first + "@" + QString::number(res.second.first) + "@" + QString::number(res.second.second)
				+ "\n";
	}
	QFileInfo fileInfo = QFileInfo(targetPath());
	outputCode(fileInfo.absolutePath() + "/" + fileInfo.completeBaseName() + ".dbg", out);

	return resultCode.remove(QRegExp("@(~|#)qrm:(/\\w+)+/\\{(\\w+-)+\\w+\\}(~|#)@"));
}

lua::LuaProcessor *MasterGeneratorBase::createLuaProcessor()
{
	return new lua::LuaProcessor(mErrorReporter, mTextLanguage, mParserErrorReporter, this);
}

PrimaryControlFlowValidator *MasterGeneratorBase::createValidator()
{
	return new PrimaryControlFlowValidator(mRepo, mErrorReporter, *mCustomizer, this);
}

void MasterGeneratorBase::beforeGeneration()
{
}

void MasterGeneratorBase::processGeneratedCode(QString &generatedCode)
{
	Q_UNUSED(generatedCode)
}

void MasterGeneratorBase::afterGeneration()
{
}

void MasterGeneratorBase::outputCode(const QString &path, const QString &code)
{
	// File must be removed to leave created and modified timestamps equal.
	QFile::remove(path);
	utils::OutFile out(path);
	out() << code;
}
<commit_msg>little changes in clear regexp<commit_after>#include <QtCore/QPair>
#include <QtCore/QStack>

#include "generatorBase/masterGeneratorBase.h"

#include <qrutils/outFile.h>
#include <qrutils/stringUtils.h>
#include <qrtext/languageToolboxInterface.h>

#include "readableControlFlowGenerator.h"
#include "gotoControlFlowGenerator.h"
#include "generatorBase/lua/luaProcessor.h"
#include "generatorBase/parts/variables.h"
#include "generatorBase/parts/subprograms.h"
#include "generatorBase/parts/threads.h"
#include "generatorBase/parts/sensors.h"
#include "generatorBase/parts/initTerminateCodeGenerator.h"

using namespace generatorBase;
using namespace qReal;

MasterGeneratorBase::MasterGeneratorBase(const qrRepo::RepoApi &repo
		, ErrorReporterInterface &errorReporter
		, const kitBase::robotModel::RobotModelManagerInterface &robotModelManager
		, qrtext::LanguageToolboxInterface &textLanguage
		, const utils::ParserErrorReporter &parserErrorReporter
		, const Id &diagramId)
	: mRepo(repo)
	, mErrorReporter(errorReporter)
	, mRobotModelManager(robotModelManager)
	, mTextLanguage(textLanguage)
	, mDiagram(diagramId)
	, mParserErrorReporter(parserErrorReporter)
{
}

void MasterGeneratorBase::setProjectDir(const QFileInfo &fileInfo)
{
	mProjectName = fileInfo.baseName();
	mProjectDir = fileInfo.absolutePath();
}

void MasterGeneratorBase::initialize()
{
	mCustomizer = createCustomizer();
	mCustomizer->factory()->initialize();
	setPathToTemplates(mCustomizer->factory()->pathToTemplates());

	mValidator = createValidator();

	mReadableControlFlowGenerator = new ReadableControlFlowGenerator(mRepo
			, mErrorReporter, *mCustomizer, *mValidator, mDiagram, this);
	mGotoControlFlowGenerator = new GotoControlFlowGenerator(mRepo
			, mErrorReporter, *mCustomizer, *mValidator, mDiagram, this);
}

QString MasterGeneratorBase::generate(const QString &indentString)
{
	if (mDiagram.isNull()) {
		mErrorReporter.addCritical(QObject::tr("There is no opened diagram"));
		return QString();
	}

	beforeGeneration();
	if (!QDir(mProjectDir).exists()) {
		QDir().mkpath(mProjectDir);
	}

	mTextLanguage.clear();
	mCustomizer->factory()->setMainDiagramId(mDiagram);

	for (parts::InitTerminateCodeGenerator *generator : mCustomizer->factory()->initTerminateGenerators()) {
		generator->reinit();
	}

	QString mainCode;
	const semantics::SemanticTree *mainControlFlow = mReadableControlFlowGenerator->generate();
	if (mainControlFlow && !mReadableControlFlowGenerator->cantBeGeneratedIntoStructuredCode()) {
		mainCode = mainControlFlow->toString(1, indentString);
		const bool subprogramsResult = mCustomizer->factory()->subprograms()->generate(mReadableControlFlowGenerator
				, indentString);
		if (!subprogramsResult) {
			if (supportsGotoGeneration()) {
				mainCode = QString();
			} else {
				return QString();
			}
		}
	} else {
		if (mReadableControlFlowGenerator->errorsOccured()) {
			return QString();
		}
	}

	if (mainCode.isEmpty() && supportsGotoGeneration()) {
		mErrorReporter.addInformation(tr("This diagram cannot be generated into the structured code."\
				" Generating it into the code with 'goto' statements."));
		const semantics::SemanticTree *gotoMainControlFlow = mGotoControlFlowGenerator->generate();
		if (gotoMainControlFlow) {
			mainCode = gotoMainControlFlow->toString(1, indentString);
			const bool gotoSubprogramsResult = mCustomizer->factory()
					->subprograms()->generate(mGotoControlFlowGenerator, indentString);
			if (!gotoSubprogramsResult) {
				mainCode = QString();
			}
		}
	}

	if (mainCode.isEmpty()) {
		const QString errorMessage = supportsGotoGeneration()
				? tr("This diagram cannot be even generated into the code with 'goto'"\
						"statements. Please contact the developers (WTF did you do?)")
				: tr("This diagram cannot be generated into the structured code.");
		mErrorReporter.addError(errorMessage);
		return QString();
	}

	QString resultCode = readTemplate("main.t");
	resultCode.replace("@@SUBPROGRAMS_FORWARDING@@", mCustomizer->factory()->subprograms()->forwardDeclarations());
	resultCode.replace("@@SUBPROGRAMS@@", mCustomizer->factory()->subprograms()->implementations());
	resultCode.replace("@@THREADS_FORWARDING@@", mCustomizer->factory()->threads().generateDeclarations());
	resultCode.replace("@@THREADS@@", mCustomizer->factory()->threads().generateImplementations(indentString));
	resultCode.replace("@@MAIN_CODE@@", mainCode);
	resultCode.replace("@@INITHOOKS@@", utils::StringUtils::addIndent(
			mCustomizer->factory()->initCode(), 1, indentString));
	resultCode.replace("@@TERMINATEHOOKS@@", utils::StringUtils::addIndent(
			mCustomizer->factory()->terminateCode(), 1, indentString));
	resultCode.replace("@@USERISRHOOKS@@", utils::StringUtils::addIndent(
			mCustomizer->factory()->isrHooksCode(), 1, indentString));
	resultCode.replace("@@VARIABLES@@", mCustomizer->factory()->variables()->generateVariableString());
	// This will remove too many empty lines
	resultCode.replace(QRegExp("\n(\n)+"), "\n\n");

	resultCode = generateLinkingInfo(resultCode);

	processGeneratedCode(resultCode);

	const QString pathToOutput = targetPath();
	outputCode(pathToOutput, resultCode);

	afterGeneration();

	return pathToOutput;
}

QString MasterGeneratorBase::generateLinkingInfo(QString &resultCode)
{
	QString const open = "@~(qrm:(/\\w+)+/\\{(\\w+-)+\\w+\\})~@";
	QString const close = "@#%1#@";
	QRegExp re;
	QStack< QPair<QString, int> > stack;
	QList< QPair<QString, QPair<int, int>> > results;
	int lineNumber = 1;

	for (QString const &line : resultCode.split("\n")){
		re.setPattern(open);
		int const pos = re.indexIn(line);
		if (pos > -1) {
			QString const id = re.cap(1);
			stack.push(QPair<QString, int>(id, lineNumber));
		}

		if (!stack.isEmpty()) {
			QString const id = stack.top().first;
			if (line.contains(close.arg(id))) {
				results.append(QPair<QString, QPair<int, int>>(id
						, QPair<int, int>(stack.top().second, lineNumber)));
				stack.pop();
			}
		}

		lineNumber++;
	}

	QString out;

	for (QPair<QString, QPair<int, int>> res : results) {
		out += res.first + "@" + QString::number(res.second.first) + "@" + QString::number(res.second.second)
				+ "\n";
	}
	QFileInfo fileInfo = QFileInfo(targetPath());
	outputCode(fileInfo.absolutePath() + "/" + fileInfo.completeBaseName() + ".dbg", out);

	return resultCode.remove(QRegExp("@(~|#)qrm:(((/\\w+)+/\\{(\\w+-)+\\w+\\})|(/))(~|#)@"));
}

lua::LuaProcessor *MasterGeneratorBase::createLuaProcessor()
{
	return new lua::LuaProcessor(mErrorReporter, mTextLanguage, mParserErrorReporter, this);
}

PrimaryControlFlowValidator *MasterGeneratorBase::createValidator()
{
	return new PrimaryControlFlowValidator(mRepo, mErrorReporter, *mCustomizer, this);
}

void MasterGeneratorBase::beforeGeneration()
{
}

void MasterGeneratorBase::processGeneratedCode(QString &generatedCode)
{
	Q_UNUSED(generatedCode)
}

void MasterGeneratorBase::afterGeneration()
{
}

void MasterGeneratorBase::outputCode(const QString &path, const QString &code)
{
	// File must be removed to leave created and modified timestamps equal.
	QFile::remove(path);
	utils::OutFile out(path);
	out() << code;
}
<|endoftext|>


<commit_before>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2013 Gauthier Brun <brun.gauthier@gmail.com>
// Copyright (C) 2013 Nicolas Carre <nicolas.carre@ensimag.fr>
// Copyright (C) 2013 Jean Ceccato <jean.ceccato@ensimag.fr>
// Copyright (C) 2013 Pierre Zoppitelli <pierre.zoppitelli@ensimag.fr>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/

// discard stack allocation as that too bypasses malloc
#define EIGEN_STACK_ALLOCATION_LIMIT 0
#define EIGEN_RUNTIME_NO_MALLOC

#include "main.h"
#include <Eigen/SVD>
#include <iostream>
#include <Eigen/LU>

#define SVD_DEFAULT(M) BDCSVD<M>
#define SVD_FOR_MIN_NORM(M) BDCSVD<M>
#include "../../test/svd_common.h"

// Check all variants of JacobiSVD
template<typename MatrixType>
void bdcsvd(const MatrixType& a = MatrixType(), bool pickrandom = true)
{
  MatrixType m = a;
  if(pickrandom)
    svd_fill_random(m);

  CALL_SUBTEST(( svd_test_all_computation_options<BDCSVD<MatrixType> >(m, false)  ));
}

template<typename MatrixType>
void bdcsvd_method()
{
  enum { Size = MatrixType::RowsAtCompileTime };
  typedef typename MatrixType::RealScalar RealScalar;
  typedef Matrix<RealScalar, Size, 1> RealVecType;
  MatrixType m = MatrixType::Identity();
  VERIFY_IS_APPROX(m.bdcSvd().singularValues(), RealVecType::Ones());
  VERIFY_RAISES_ASSERT(m.bdcSvd().matrixU());
  VERIFY_RAISES_ASSERT(m.bdcSvd().matrixV());
  VERIFY_IS_APPROX(m.bdcSvd(ComputeFullU|ComputeFullV).solve(m), m);
}

// compare the Singular values returned with Jacobi and Bdc
template<typename MatrixType>
void compare_bdc_jacobi(const MatrixType& a = MatrixType(), unsigned int computationOptions = 0)
{
  MatrixType m = MatrixType::Random(a.rows(), a.cols());
  BDCSVD<MatrixType> bdc_svd(m);
  JacobiSVD<MatrixType> jacobi_svd(m);
  VERIFY_IS_APPROX(bdc_svd.singularValues(), jacobi_svd.singularValues());
  if(computationOptions & ComputeFullU) VERIFY_IS_APPROX(bdc_svd.matrixU(), jacobi_svd.matrixU());
  if(computationOptions & ComputeThinU) VERIFY_IS_APPROX(bdc_svd.matrixU(), jacobi_svd.matrixU());
  if(computationOptions & ComputeFullV) VERIFY_IS_APPROX(bdc_svd.matrixV(), jacobi_svd.matrixV());
  if(computationOptions & ComputeThinV) VERIFY_IS_APPROX(bdc_svd.matrixV(), jacobi_svd.matrixV());
}

void test_bdcsvd()
{
  CALL_SUBTEST_3(( svd_verify_assert<BDCSVD<Matrix3f>  >(Matrix3f()) ));
  CALL_SUBTEST_4(( svd_verify_assert<BDCSVD<Matrix4d>  >(Matrix4d()) ));
  CALL_SUBTEST_7(( svd_verify_assert<BDCSVD<MatrixXf>  >(MatrixXf(10,12)) ));
  CALL_SUBTEST_8(( svd_verify_assert<BDCSVD<MatrixXcd> >(MatrixXcd(7,5)) ));

  CALL_SUBTEST_1(( svd_all_trivial_2x2(bdcsvd<Matrix2cd>) ));
  CALL_SUBTEST_1(( svd_all_trivial_2x2(bdcsvd<Matrix2d>) ));

  for(int i = 0; i < g_repeat; i++) {
    CALL_SUBTEST_3(( bdcsvd<Matrix3f>() ));
    CALL_SUBTEST_4(( bdcsvd<Matrix4d>() ));
    CALL_SUBTEST_5(( bdcsvd<Matrix<float,3,5> >() ));

    int r = internal::random<int>(1, EIGEN_TEST_MAX_SIZE/2),
        c = internal::random<int>(1, EIGEN_TEST_MAX_SIZE/2);

    TEST_SET_BUT_UNUSED_VARIABLE(r)
    TEST_SET_BUT_UNUSED_VARIABLE(c)

    CALL_SUBTEST_6((  bdcsvd(Matrix<double,Dynamic,2>(r,2)) ));
    CALL_SUBTEST_7((  bdcsvd(MatrixXf(r,c)) ));
    CALL_SUBTEST_7((  compare_bdc_jacobi(MatrixXf(r,c)) ));
    CALL_SUBTEST_10(( bdcsvd(MatrixXd(r,c)) ));
    CALL_SUBTEST_10(( compare_bdc_jacobi(MatrixXd(r,c)) ));
    CALL_SUBTEST_8((  bdcsvd(MatrixXcd(r,c)) ));
    CALL_SUBTEST_8((  compare_bdc_jacobi(MatrixXcd(r,c)) ));

    // Test on inf/nan matrix
    CALL_SUBTEST_7(  (svd_inf_nan<BDCSVD<MatrixXf>, MatrixXf>()) );
    CALL_SUBTEST_10( (svd_inf_nan<BDCSVD<MatrixXd>, MatrixXd>()) );
  }

  // test matrixbase method
  CALL_SUBTEST_1(( bdcsvd_method<Matrix2cd>() ));
  CALL_SUBTEST_3(( bdcsvd_method<Matrix3f>() ));

  // Test problem size constructors
  CALL_SUBTEST_7( BDCSVD<MatrixXf>(10,10) );

  // Check that preallocation avoids subsequent mallocs
  CALL_SUBTEST_9( svd_preallocate() );

  CALL_SUBTEST_2( svd_underoverflow() );
}

<commit_msg>Fixed include in bdcsvd.cpp<commit_after>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2013 Gauthier Brun <brun.gauthier@gmail.com>
// Copyright (C) 2013 Nicolas Carre <nicolas.carre@ensimag.fr>
// Copyright (C) 2013 Jean Ceccato <jean.ceccato@ensimag.fr>
// Copyright (C) 2013 Pierre Zoppitelli <pierre.zoppitelli@ensimag.fr>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/

// discard stack allocation as that too bypasses malloc
#define EIGEN_STACK_ALLOCATION_LIMIT 0
#define EIGEN_RUNTIME_NO_MALLOC

#include "main.h"
#include <Eigen/SVD>
#include <iostream>
#include <Eigen/LU>

#define SVD_DEFAULT(M) BDCSVD<M>
#define SVD_FOR_MIN_NORM(M) BDCSVD<M>
#include "svd_common.h"

// Check all variants of JacobiSVD
template<typename MatrixType>
void bdcsvd(const MatrixType& a = MatrixType(), bool pickrandom = true)
{
  MatrixType m = a;
  if(pickrandom)
    svd_fill_random(m);

  CALL_SUBTEST(( svd_test_all_computation_options<BDCSVD<MatrixType> >(m, false)  ));
}

template<typename MatrixType>
void bdcsvd_method()
{
  enum { Size = MatrixType::RowsAtCompileTime };
  typedef typename MatrixType::RealScalar RealScalar;
  typedef Matrix<RealScalar, Size, 1> RealVecType;
  MatrixType m = MatrixType::Identity();
  VERIFY_IS_APPROX(m.bdcSvd().singularValues(), RealVecType::Ones());
  VERIFY_RAISES_ASSERT(m.bdcSvd().matrixU());
  VERIFY_RAISES_ASSERT(m.bdcSvd().matrixV());
  VERIFY_IS_APPROX(m.bdcSvd(ComputeFullU|ComputeFullV).solve(m), m);
}

// compare the Singular values returned with Jacobi and Bdc
template<typename MatrixType>
void compare_bdc_jacobi(const MatrixType& a = MatrixType(), unsigned int computationOptions = 0)
{
  MatrixType m = MatrixType::Random(a.rows(), a.cols());
  BDCSVD<MatrixType> bdc_svd(m);
  JacobiSVD<MatrixType> jacobi_svd(m);
  VERIFY_IS_APPROX(bdc_svd.singularValues(), jacobi_svd.singularValues());
  if(computationOptions & ComputeFullU) VERIFY_IS_APPROX(bdc_svd.matrixU(), jacobi_svd.matrixU());
  if(computationOptions & ComputeThinU) VERIFY_IS_APPROX(bdc_svd.matrixU(), jacobi_svd.matrixU());
  if(computationOptions & ComputeFullV) VERIFY_IS_APPROX(bdc_svd.matrixV(), jacobi_svd.matrixV());
  if(computationOptions & ComputeThinV) VERIFY_IS_APPROX(bdc_svd.matrixV(), jacobi_svd.matrixV());
}

void test_bdcsvd()
{
  CALL_SUBTEST_3(( svd_verify_assert<BDCSVD<Matrix3f>  >(Matrix3f()) ));
  CALL_SUBTEST_4(( svd_verify_assert<BDCSVD<Matrix4d>  >(Matrix4d()) ));
  CALL_SUBTEST_7(( svd_verify_assert<BDCSVD<MatrixXf>  >(MatrixXf(10,12)) ));
  CALL_SUBTEST_8(( svd_verify_assert<BDCSVD<MatrixXcd> >(MatrixXcd(7,5)) ));

  CALL_SUBTEST_1(( svd_all_trivial_2x2(bdcsvd<Matrix2cd>) ));
  CALL_SUBTEST_1(( svd_all_trivial_2x2(bdcsvd<Matrix2d>) ));

  for(int i = 0; i < g_repeat; i++) {
    CALL_SUBTEST_3(( bdcsvd<Matrix3f>() ));
    CALL_SUBTEST_4(( bdcsvd<Matrix4d>() ));
    CALL_SUBTEST_5(( bdcsvd<Matrix<float,3,5> >() ));

    int r = internal::random<int>(1, EIGEN_TEST_MAX_SIZE/2),
        c = internal::random<int>(1, EIGEN_TEST_MAX_SIZE/2);

    TEST_SET_BUT_UNUSED_VARIABLE(r)
    TEST_SET_BUT_UNUSED_VARIABLE(c)

    CALL_SUBTEST_6((  bdcsvd(Matrix<double,Dynamic,2>(r,2)) ));
    CALL_SUBTEST_7((  bdcsvd(MatrixXf(r,c)) ));
    CALL_SUBTEST_7((  compare_bdc_jacobi(MatrixXf(r,c)) ));
    CALL_SUBTEST_10(( bdcsvd(MatrixXd(r,c)) ));
    CALL_SUBTEST_10(( compare_bdc_jacobi(MatrixXd(r,c)) ));
    CALL_SUBTEST_8((  bdcsvd(MatrixXcd(r,c)) ));
    CALL_SUBTEST_8((  compare_bdc_jacobi(MatrixXcd(r,c)) ));

    // Test on inf/nan matrix
    CALL_SUBTEST_7(  (svd_inf_nan<BDCSVD<MatrixXf>, MatrixXf>()) );
    CALL_SUBTEST_10( (svd_inf_nan<BDCSVD<MatrixXd>, MatrixXd>()) );
  }

  // test matrixbase method
  CALL_SUBTEST_1(( bdcsvd_method<Matrix2cd>() ));
  CALL_SUBTEST_3(( bdcsvd_method<Matrix3f>() ));

  // Test problem size constructors
  CALL_SUBTEST_7( BDCSVD<MatrixXf>(10,10) );

  // Check that preallocation avoids subsequent mallocs
  CALL_SUBTEST_9( svd_preallocate() );

  CALL_SUBTEST_2( svd_underoverflow() );
}

<|endoftext|>


<commit_before>//------------------------------------------------------------------------------
//  TestApp.cc
//------------------------------------------------------------------------------
#include "Pre.h"
#include "Core/App.h"
#include "Gfx/Gfx.h"
#include "Gfx/Util/RawMeshLoader.h"
#include "Gfx/Util/ShapeBuilder.h"
#include "glm/mat4x4.hpp"
#include "glm/gtc/matrix_transform.hpp"
#include "shaders.h"

using namespace Oryol;

// derived application class
class TestApp : public App {
public:
    AppState::Code OnRunning();
    AppState::Code OnInit();
    AppState::Code OnCleanup();
private:
    glm::mat4 computeMVP(const glm::mat4& proj, float32 rotX, float32 rotY, const glm::vec3& pos);

    GfxId renderTarget;
    GfxId offscreenDrawState;
    GfxId displayDrawState;
    glm::mat4 view;
    glm::mat4 offscreenProj;
    glm::mat4 displayProj;
    float32 angleX = 0.0f;
    float32 angleY = 0.0f;
};
OryolMain(TestApp);

//------------------------------------------------------------------------------
AppState::Code
TestApp::OnRunning() {

    // update angles
    this->angleY += 0.01f;
    this->angleX += 0.02f;

    // render donut to offscreen render target
    Gfx::ApplyOffscreenRenderTarget(this->renderTarget);
    Gfx::Clear(PixelChannel::All, glm::vec4(0.25f));
    Gfx::ApplyDrawState(this->offscreenDrawState);
    glm::mat4 donutMVP = this->computeMVP(this->offscreenProj, this->angleX, this->angleY, glm::vec3(0.0f, 0.0f, -3.0f));
    Gfx::ApplyVariable(Shaders::RenderTarget::ModelViewProjection, donutMVP);
    Gfx::Draw(0);

    // render sphere to display, with offscreen render target as texture
    Gfx::ApplyDefaultRenderTarget();
    Gfx::Clear(PixelChannel::All, glm::vec4(0.25f), 1.0f, 0);
    Gfx::ApplyDrawState(this->displayDrawState);
    glm::mat4 sphereMVP = this->computeMVP(this->displayProj, -this->angleX * 0.25f, this->angleY * 0.25f, glm::vec3(0.0f, 0.0f, -1.5f));
    Gfx::ApplyVariable(Shaders::Main::ModelViewProjection, sphereMVP);
    Gfx::ApplyVariable(Shaders::Main::Texture, this->renderTarget);
    Gfx::Draw(0);

    Gfx::CommitFrame();

    // continue running or quit?
    return Gfx::QuitRequested() ? AppState::Cleanup : AppState::Running;
}

//------------------------------------------------------------------------------
AppState::Code
TestApp::OnInit() {
    // setup rendering system
    auto gfxSetup = GfxSetup::WindowMSAA4(800, 600, "Oryol Test App");
    gfxSetup.Loaders.Add(RawMeshLoader::Creator());
    Gfx::Setup(gfxSetup);

    // create an offscreen render target, we explicitly want repeat texture wrap mode
    // and linear blending...
    auto rtSetup = TextureSetup::RenderTarget(128, 128);
    rtSetup.ColorFormat = PixelFormat::RGB8;
    rtSetup.DepthFormat = PixelFormat::D16;
    rtSetup.WrapU = TextureWrapMode::Repeat;
    rtSetup.WrapV = TextureWrapMode::Repeat;
    rtSetup.MagFilter = TextureFilterMode::Linear;
    rtSetup.MinFilter = TextureFilterMode::Linear;
    this->renderTarget = Gfx::CreateResource(rtSetup);

    // create a donut (this will be rendered into the offscreen render target)
    ShapeBuilder shapeBuilder;
    shapeBuilder.Layout()
        .Add(VertexAttr::Position, VertexFormat::Float3)
        .Add(VertexAttr::Normal, VertexFormat::Byte4N);
    shapeBuilder.Box(1.0f, 1.0f, 1.0f, 1).Build();
    GfxId torus = Gfx::CreateResource(MeshSetup::FromStream(), shapeBuilder.Result());

    // create a sphere mesh with normals and uv coords
    shapeBuilder.Clear();
    shapeBuilder.Layout()
        .Add(VertexAttr::Position, VertexFormat::Float3)
        .Add(VertexAttr::Normal, VertexFormat::Byte4N)
        .Add(VertexAttr::TexCoord0, VertexFormat::Float2);
    shapeBuilder.Sphere(0.5f, 72.0f, 40.0f).Build();
    GfxId sphere = Gfx::CreateResource(MeshSetup::FromStream(), shapeBuilder.Result());

    // create shaders
    GfxId offScreenProg = Gfx::CreateResource(Shaders::RenderTarget::CreateSetup());
    GfxId dispProg = Gfx::CreateResource(Shaders::Main::CreateSetup());

    // create one draw state for offscreen rendering, and one draw state for main target rendering
    auto offdsSetup = DrawStateSetup::FromMeshAndProg(torus, offScreenProg);
    offdsSetup.DepthStencilState.DepthWriteEnabled = true;
    offdsSetup.DepthStencilState.DepthCmpFunc = CompareFunc::LessEqual;
    this->offscreenDrawState = Gfx::CreateResource(offdsSetup);
    auto dispdsSetup = DrawStateSetup::FromMeshAndProg(sphere, dispProg);
    dispdsSetup.DepthStencilState.DepthWriteEnabled = true;
    dispdsSetup.DepthStencilState.DepthCmpFunc = CompareFunc::LessEqual;
    this->displayDrawState = Gfx::CreateResource(dispdsSetup);

    // setup static transform matrices
    float32 fbWidth = Gfx::DisplayAttrs().FramebufferWidth;
    float32 fbHeight = Gfx::DisplayAttrs().FramebufferHeight;
    this->offscreenProj = glm::perspective(glm::radians(45.0f), 1.0f, 0.01f, 20.0f);
    this->displayProj = glm::perspectiveFov(glm::radians(45.0f), fbWidth, fbHeight, 0.01f, 100.0f);
    this->view = glm::mat4();

    return App::OnInit();
}

//------------------------------------------------------------------------------
AppState::Code
TestApp::OnCleanup() {
    // cleanup everything
    this->offscreenDrawState.Release();
    this->displayDrawState.Release();
    this->renderTarget.Release();
    Gfx::Discard();
    return App::OnCleanup();
}

//------------------------------------------------------------------------------
glm::mat4
TestApp::computeMVP(const glm::mat4& proj, float32 rotX, float32 rotY, const glm::vec3& pos) {
    glm::mat4 modelTform = glm::translate(glm::mat4(), pos);
    modelTform = glm::rotate(modelTform, rotX, glm::vec3(1.0f, 0.0f, 0.0f));
    modelTform = glm::rotate(modelTform, rotY, glm::vec3(0.0f, 1.0f, 0.0f));
    return proj * this->view * modelTform;
}
<commit_msg>ShapeBuilder API fixes (to be conform with MeshBuilder)<commit_after>//------------------------------------------------------------------------------
//  TestApp.cc
//------------------------------------------------------------------------------
#include "Pre.h"
#include "Core/App.h"
#include "Gfx/Gfx.h"
#include "Gfx/Util/RawMeshLoader.h"
#include "Gfx/Util/ShapeBuilder.h"
#include "glm/mat4x4.hpp"
#include "glm/gtc/matrix_transform.hpp"
#include "shaders.h"

using namespace Oryol;

// derived application class
class TestApp : public App {
public:
    AppState::Code OnRunning();
    AppState::Code OnInit();
    AppState::Code OnCleanup();
private:
    glm::mat4 computeMVP(const glm::mat4& proj, float32 rotX, float32 rotY, const glm::vec3& pos);

    GfxId renderTarget;
    GfxId offscreenDrawState;
    GfxId displayDrawState;
    glm::mat4 view;
    glm::mat4 offscreenProj;
    glm::mat4 displayProj;
    float32 angleX = 0.0f;
    float32 angleY = 0.0f;
};
OryolMain(TestApp);

//------------------------------------------------------------------------------
AppState::Code
TestApp::OnRunning() {

    // update angles
    this->angleY += 0.01f;
    this->angleX += 0.02f;

    // render donut to offscreen render target
    Gfx::ApplyOffscreenRenderTarget(this->renderTarget);
    Gfx::Clear(PixelChannel::All, glm::vec4(0.25f));
    Gfx::ApplyDrawState(this->offscreenDrawState);
    glm::mat4 donutMVP = this->computeMVP(this->offscreenProj, this->angleX, this->angleY, glm::vec3(0.0f, 0.0f, -3.0f));
    Gfx::ApplyVariable(Shaders::RenderTarget::ModelViewProjection, donutMVP);
    Gfx::Draw(0);

    // render sphere to display, with offscreen render target as texture
    Gfx::ApplyDefaultRenderTarget();
    Gfx::Clear(PixelChannel::All, glm::vec4(0.25f), 1.0f, 0);
    Gfx::ApplyDrawState(this->displayDrawState);
    glm::mat4 sphereMVP = this->computeMVP(this->displayProj, -this->angleX * 0.25f, this->angleY * 0.25f, glm::vec3(0.0f, 0.0f, -1.5f));
    Gfx::ApplyVariable(Shaders::Main::ModelViewProjection, sphereMVP);
    Gfx::ApplyVariable(Shaders::Main::Texture, this->renderTarget);
    Gfx::Draw(0);

    Gfx::CommitFrame();

    // continue running or quit?
    return Gfx::QuitRequested() ? AppState::Cleanup : AppState::Running;
}

//------------------------------------------------------------------------------
AppState::Code
TestApp::OnInit() {
    // setup rendering system
    auto gfxSetup = GfxSetup::WindowMSAA4(800, 600, "Oryol Test App");
    gfxSetup.Loaders.Add(RawMeshLoader::Creator());
    Gfx::Setup(gfxSetup);

    // create an offscreen render target, we explicitly want repeat texture wrap mode
    // and linear blending...
    auto rtSetup = TextureSetup::RenderTarget(128, 128);
    rtSetup.ColorFormat = PixelFormat::RGB8;
    rtSetup.DepthFormat = PixelFormat::D16;
    rtSetup.WrapU = TextureWrapMode::Repeat;
    rtSetup.WrapV = TextureWrapMode::Repeat;
    rtSetup.MagFilter = TextureFilterMode::Linear;
    rtSetup.MinFilter = TextureFilterMode::Linear;
    this->renderTarget = Gfx::CreateResource(rtSetup);

    // create a donut (this will be rendered into the offscreen render target)
    ShapeBuilder shapeBuilder;
    shapeBuilder.Layout
        .Add(VertexAttr::Position, VertexFormat::Float3)
        .Add(VertexAttr::Normal, VertexFormat::Byte4N);
    shapeBuilder.Box(1.0f, 1.0f, 1.0f, 1).Build();
    GfxId torus = Gfx::CreateResource(MeshSetup::FromStream(), shapeBuilder.Result());

    // create a sphere mesh with normals and uv coords
    shapeBuilder.Clear();
    shapeBuilder.Layout
        .Add(VertexAttr::Position, VertexFormat::Float3)
        .Add(VertexAttr::Normal, VertexFormat::Byte4N)
        .Add(VertexAttr::TexCoord0, VertexFormat::Float2);
    shapeBuilder.Sphere(0.5f, 72.0f, 40.0f).Build();
    GfxId sphere = Gfx::CreateResource(MeshSetup::FromStream(), shapeBuilder.Result());

    // create shaders
    GfxId offScreenProg = Gfx::CreateResource(Shaders::RenderTarget::CreateSetup());
    GfxId dispProg = Gfx::CreateResource(Shaders::Main::CreateSetup());

    // create one draw state for offscreen rendering, and one draw state for main target rendering
    auto offdsSetup = DrawStateSetup::FromMeshAndProg(torus, offScreenProg);
    offdsSetup.DepthStencilState.DepthWriteEnabled = true;
    offdsSetup.DepthStencilState.DepthCmpFunc = CompareFunc::LessEqual;
    this->offscreenDrawState = Gfx::CreateResource(offdsSetup);
    auto dispdsSetup = DrawStateSetup::FromMeshAndProg(sphere, dispProg);
    dispdsSetup.DepthStencilState.DepthWriteEnabled = true;
    dispdsSetup.DepthStencilState.DepthCmpFunc = CompareFunc::LessEqual;
    this->displayDrawState = Gfx::CreateResource(dispdsSetup);

    // setup static transform matrices
    float32 fbWidth = Gfx::DisplayAttrs().FramebufferWidth;
    float32 fbHeight = Gfx::DisplayAttrs().FramebufferHeight;
    this->offscreenProj = glm::perspective(glm::radians(45.0f), 1.0f, 0.01f, 20.0f);
    this->displayProj = glm::perspectiveFov(glm::radians(45.0f), fbWidth, fbHeight, 0.01f, 100.0f);
    this->view = glm::mat4();

    return App::OnInit();
}

//------------------------------------------------------------------------------
AppState::Code
TestApp::OnCleanup() {
    // cleanup everything
    this->offscreenDrawState.Release();
    this->displayDrawState.Release();
    this->renderTarget.Release();
    Gfx::Discard();
    return App::OnCleanup();
}

//------------------------------------------------------------------------------
glm::mat4
TestApp::computeMVP(const glm::mat4& proj, float32 rotX, float32 rotY, const glm::vec3& pos) {
    glm::mat4 modelTform = glm::translate(glm::mat4(), pos);
    modelTform = glm::rotate(modelTform, rotX, glm::vec3(1.0f, 0.0f, 0.0f));
    modelTform = glm::rotate(modelTform, rotY, glm::vec3(0.0f, 1.0f, 0.0f));
    return proj * this->view * modelTform;
}
<|endoftext|>


<commit_before>//------------------------------------------------------------------------------
//  TestApp.cc
//------------------------------------------------------------------------------
#include "Pre.h"
#include "Core/Main.h"
#include "Gfx/Gfx.h"
#include "Assets/Gfx/ShapeBuilder.h"
#include "glm/mat4x4.hpp"
#include "glm/gtc/matrix_transform.hpp"
#include "shaders.h"

using namespace Oryol;

// derived application class
class TestApp : public App {
public:
    AppState::Code OnRunning();
    AppState::Code OnInit();
    AppState::Code OnCleanup();
private:
    glm::mat4 computeMVP(const glm::mat4& proj, float32 rotX, float32 rotY, const glm::vec3& pos);

    Id renderTarget;
    DrawState offscrDrawState;
    DrawState mainDrawState;
    ClearState offscrClearState;
    ClearState mainClearState;
    OffscreenShader::VSParams offscrVSParams;
    MainShader::VSParams mainVSParams;
    glm::mat4 view;
    glm::mat4 offscreenProj;
    glm::mat4 displayProj;
    float32 angleX = 0.0f;
    float32 angleY = 0.0f;
};
OryolMain(TestApp);

//------------------------------------------------------------------------------
AppState::Code
TestApp::OnRunning() {

    // update animated parameters
    this->angleY += 0.01f;
    this->angleX += 0.02f;
    this->offscrVSParams.ModelViewProjection = this->computeMVP(this->offscreenProj, this->angleX, this->angleY, glm::vec3(0.0f, 0.0f, -3.0f));
    this->mainVSParams.ModelViewProjection = this->computeMVP(this->displayProj, -this->angleX * 0.25f, this->angleY * 0.25f, glm::vec3(0.0f, 0.0f, -1.5f));;

    // render donut to offscreen render target
    Gfx::ApplyRenderTarget(this->renderTarget, this->offscrClearState);
    Gfx::ApplyDrawState(this->offscrDrawState);
    Gfx::ApplyUniformBlock(this->offscrVSParams);
    Gfx::Draw(0);

    // render sphere to display, with offscreen render target as texture
    Gfx::ApplyDefaultRenderTarget(this->mainClearState);
    Gfx::ApplyDrawState(this->mainDrawState);
    Gfx::ApplyUniformBlock(this->mainVSParams);
    Gfx::Draw(0);

    Gfx::CommitFrame();

    // continue running or quit?
    return Gfx::QuitRequested() ? AppState::Cleanup : AppState::Running;
}

//------------------------------------------------------------------------------
AppState::Code
TestApp::OnInit() {
    // setup rendering system
    auto gfxSetup = GfxSetup::WindowMSAA4(800, 600, "Oryol Test App");
    Gfx::Setup(gfxSetup);

    // create an offscreen render target, we explicitly want repeat texture wrap mode
    // and linear blending...
    auto rtSetup = TextureSetup::RenderTarget(128, 128);
    rtSetup.ColorFormat = PixelFormat::RGBA8;
    rtSetup.DepthFormat = PixelFormat::DEPTH;
    rtSetup.Sampler.WrapU = TextureWrapMode::Repeat;
    rtSetup.Sampler.WrapV = TextureWrapMode::Repeat;
    rtSetup.Sampler.MagFilter = TextureFilterMode::Linear;
    rtSetup.Sampler.MinFilter = TextureFilterMode::Linear;
    this->renderTarget = Gfx::CreateResource(rtSetup);

    // create offscreen rendering resources
    ShapeBuilder shapeBuilder;
    shapeBuilder.Layout
        .Add(VertexAttr::Position, VertexFormat::Float3)
        .Add(VertexAttr::Normal, VertexFormat::Byte4N);
    shapeBuilder.Box(1.0f, 1.0f, 1.0f, 1);
    this->offscrDrawState.Mesh[0] = Gfx::CreateResource(shapeBuilder.Build());
    Id offScreenShader = Gfx::CreateResource(OffscreenShader::Setup());
    auto offPipSetup = PipelineSetup::FromLayoutAndShader(shapeBuilder.Layout, offScreenShader);
    offPipSetup.DepthStencilState.DepthWriteEnabled = true;
    offPipSetup.DepthStencilState.DepthCmpFunc = CompareFunc::LessEqual;
    offPipSetup.BlendState.ColorFormat = rtSetup.ColorFormat;
    offPipSetup.BlendState.DepthFormat = rtSetup.DepthFormat;
    this->offscrDrawState.Pipeline = Gfx::CreateResource(offPipSetup);

    // create display rendering resources
    shapeBuilder.Layout
        .Clear()
        .Add(VertexAttr::Position, VertexFormat::Float3)
        .Add(VertexAttr::Normal, VertexFormat::Byte4N)
        .Add(VertexAttr::TexCoord0, VertexFormat::Float2);
    shapeBuilder.Sphere(0.5f, 72.0f, 40.0f);
    this->mainDrawState.Mesh[0] = Gfx::CreateResource(shapeBuilder.Build());
    Id dispShader = Gfx::CreateResource(MainShader::Setup());
    auto dispPipSetup = PipelineSetup::FromLayoutAndShader(shapeBuilder.Layout, dispShader);
    dispPipSetup.DepthStencilState.DepthWriteEnabled = true;
    dispPipSetup.DepthStencilState.DepthCmpFunc = CompareFunc::LessEqual;
    dispPipSetup.RasterizerState.SampleCount = gfxSetup.SampleCount;
    this->mainDrawState.Pipeline = Gfx::CreateResource(dispPipSetup);
    this->mainDrawState.FSTexture[Textures::Texture] = this->renderTarget;

    // setup clear states
    this->offscrClearState.Color = glm::vec4(1.0f, 0.5f, 0.25f, 1.0f);
    this->mainClearState.Color = glm::vec4(0.25f, 0.5f, 1.0f, 1.0f);

    // setup static transform matrices
    float32 fbWidth = Gfx::DisplayAttrs().FramebufferWidth;
    float32 fbHeight = Gfx::DisplayAttrs().FramebufferHeight;
    this->offscreenProj = glm::perspective(glm::radians(45.0f), 1.0f, 0.01f, 20.0f);
    this->displayProj = glm::perspectiveFov(glm::radians(45.0f), fbWidth, fbHeight, 0.01f, 100.0f);
    this->view = glm::mat4();

    return App::OnInit();
}

//------------------------------------------------------------------------------
AppState::Code
TestApp::OnCleanup() {
    Gfx::Discard();
    return App::OnCleanup();
}

//------------------------------------------------------------------------------
glm::mat4
TestApp::computeMVP(const glm::mat4& proj, float32 rotX, float32 rotY, const glm::vec3& pos) {
    glm::mat4 modelTform = glm::translate(glm::mat4(), pos);
    modelTform = glm::rotate(modelTform, rotX, glm::vec3(1.0f, 0.0f, 0.0f));
    modelTform = glm::rotate(modelTform, rotY, glm::vec3(0.0f, 1.0f, 0.0f));
    return proj * this->view * modelTform;
}
<commit_msg>Fixes for Oryol render pass changes<commit_after>//------------------------------------------------------------------------------
//  TestApp.cc
//------------------------------------------------------------------------------
#include "Pre.h"
#include "Core/Main.h"
#include "Gfx/Gfx.h"
#include "Assets/Gfx/ShapeBuilder.h"
#include "glm/mat4x4.hpp"
#include "glm/gtc/matrix_transform.hpp"
#include "shaders.h"

using namespace Oryol;

// derived application class
class TestApp : public App {
public:
    AppState::Code OnRunning();
    AppState::Code OnInit();
    AppState::Code OnCleanup();
private:
    glm::mat4 computeMVP(const glm::mat4& proj, float32 rotX, float32 rotY, const glm::vec3& pos);

    Id renderPass;
    DrawState offscrDrawState;
    DrawState mainDrawState;
    OffscreenShader::VSParams offscrVSParams;
    MainShader::VSParams mainVSParams;
    glm::mat4 view;
    glm::mat4 offscreenProj;
    glm::mat4 displayProj;
    float32 angleX = 0.0f;
    float32 angleY = 0.0f;
};
OryolMain(TestApp);

//------------------------------------------------------------------------------
AppState::Code
TestApp::OnRunning() {

    // update animated parameters
    this->angleY += 0.01f;
    this->angleX += 0.02f;
    this->offscrVSParams.ModelViewProjection = this->computeMVP(this->offscreenProj, this->angleX, this->angleY, glm::vec3(0.0f, 0.0f, -3.0f));
    this->mainVSParams.ModelViewProjection = this->computeMVP(this->displayProj, -this->angleX * 0.25f, this->angleY * 0.25f, glm::vec3(0.0f, 0.0f, -1.5f));;

    // render donut to offscreen render target
    Gfx::BeginPass(this->renderPass);
    Gfx::ApplyDrawState(this->offscrDrawState);
    Gfx::ApplyUniformBlock(this->offscrVSParams);
    Gfx::Draw(0);
    Gfx::EndPass();

    // render sphere to display, with offscreen render target as texture
    Gfx::BeginPass();
    Gfx::ApplyDrawState(this->mainDrawState);
    Gfx::ApplyUniformBlock(this->mainVSParams);
    Gfx::Draw(0);
    Gfx::EndPass();

    Gfx::CommitFrame();

    // continue running or quit?
    return Gfx::QuitRequested() ? AppState::Cleanup : AppState::Running;
}

//------------------------------------------------------------------------------
AppState::Code
TestApp::OnInit() {
    // setup rendering system
    auto gfxSetup = GfxSetup::WindowMSAA4(800, 600, "Oryol Test App");
    gfxSetup.DefaultPassAction = PassAction::Clear(glm::vec4(0.25f, 0.45f, 0.65f, 1.0f));
    Gfx::Setup(gfxSetup);

    // create an offscreen render target, we explicitly want repeat texture wrap mode
    // and linear blending...
    auto rtSetup = TextureSetup::RenderTarget2D(128, 128, PixelFormat::RGBA8, PixelFormat::DEPTH);
    rtSetup.Sampler.WrapU = TextureWrapMode::Repeat;
    rtSetup.Sampler.WrapV = TextureWrapMode::Repeat;
    rtSetup.Sampler.MagFilter = TextureFilterMode::Linear;
    rtSetup.Sampler.MinFilter = TextureFilterMode::Linear;
    Id rtTex = Gfx::CreateResource(rtSetup);
    auto passSetup = PassSetup::From(rtTex, rtTex);
    passSetup.DefaultAction = PassAction::Clear(glm::vec4(0.25f, 0.65f, 0.45f, 1.0f));
    this->renderPass = Gfx::CreateResource(passSetup);

    // create offscreen rendering resources
    ShapeBuilder shapeBuilder;
    shapeBuilder.Layout
        .Add(VertexAttr::Position, VertexFormat::Float3)
        .Add(VertexAttr::Normal, VertexFormat::Byte4N);
    shapeBuilder.Box(1.0f, 1.0f, 1.0f, 1);
    this->offscrDrawState.Mesh[0] = Gfx::CreateResource(shapeBuilder.Build());
    Id offScreenShader = Gfx::CreateResource(OffscreenShader::Setup());
    auto offPipSetup = PipelineSetup::FromLayoutAndShader(shapeBuilder.Layout, offScreenShader);
    offPipSetup.DepthStencilState.DepthWriteEnabled = true;
    offPipSetup.DepthStencilState.DepthCmpFunc = CompareFunc::LessEqual;
    offPipSetup.BlendState.ColorFormat = rtSetup.ColorFormat;
    offPipSetup.BlendState.DepthFormat = rtSetup.DepthFormat;
    this->offscrDrawState.Pipeline = Gfx::CreateResource(offPipSetup);

    // create display rendering resources
    shapeBuilder.Layout
        .Clear()
        .Add(VertexAttr::Position, VertexFormat::Float3)
        .Add(VertexAttr::Normal, VertexFormat::Byte4N)
        .Add(VertexAttr::TexCoord0, VertexFormat::Float2);
    shapeBuilder.Sphere(0.5f, 72.0f, 40.0f);
    this->mainDrawState.Mesh[0] = Gfx::CreateResource(shapeBuilder.Build());
    Id dispShader = Gfx::CreateResource(MainShader::Setup());
    auto dispPipSetup = PipelineSetup::FromLayoutAndShader(shapeBuilder.Layout, dispShader);
    dispPipSetup.DepthStencilState.DepthWriteEnabled = true;
    dispPipSetup.DepthStencilState.DepthCmpFunc = CompareFunc::LessEqual;
    dispPipSetup.RasterizerState.SampleCount = gfxSetup.SampleCount;
    this->mainDrawState.Pipeline = Gfx::CreateResource(dispPipSetup);
    this->mainDrawState.FSTexture[Textures::Texture] = rtTex;

    // setup static transform matrices
    float32 fbWidth = Gfx::DisplayAttrs().FramebufferWidth;
    float32 fbHeight = Gfx::DisplayAttrs().FramebufferHeight;
    this->offscreenProj = glm::perspective(glm::radians(45.0f), 1.0f, 0.01f, 20.0f);
    this->displayProj = glm::perspectiveFov(glm::radians(45.0f), fbWidth, fbHeight, 0.01f, 100.0f);
    this->view = glm::mat4();

    return App::OnInit();
}

//------------------------------------------------------------------------------
AppState::Code
TestApp::OnCleanup() {
    Gfx::Discard();
    return App::OnCleanup();
}

//------------------------------------------------------------------------------
glm::mat4
TestApp::computeMVP(const glm::mat4& proj, float32 rotX, float32 rotY, const glm::vec3& pos) {
    glm::mat4 modelTform = glm::translate(glm::mat4(), pos);
    modelTform = glm::rotate(modelTform, rotX, glm::vec3(1.0f, 0.0f, 0.0f));
    modelTform = glm::rotate(modelTform, rotY, glm::vec3(0.0f, 1.0f, 0.0f));
    return proj * this->view * modelTform;
}
<|endoftext|>


<commit_before>/***********************************************************************
 test/string.cpp - Tests the behavior of mysqlpp::String, particularly
	its data conversion methods.

 Copyright (c) 2007-2008 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the
 CREDITS file in the top directory of the distribution for details.

 This file is part of MySQL++.

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

 MySQL++ 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 MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#include <mysql++.h>

#include <iostream>

// Does an equality comparison on the value, forcing the string to
// convert itself to T on the way.  Note that we do this test in terms
// of greater and less than to avoid pedantic GCC warnings for the
// floating point type tests.
template <typename T>
static bool
test_equality(const mysqlpp::String& s, T value)
{
	T converted = s.conv(value);
	if ((value < converted) || (value > converted)) {
		std::cerr << "Type conversion to " << typeid(T).name() <<
				" failed: \"" << s << "\" != \"" << value << "\"." <<
				std::endl;
		return false;
	}
	else {
		return true;
	}
}

// Check that we can convert strings with decimals in them to native
// floating-point values, regardless of locale.
static bool
test_float_conversion()
{
	// This stuff should just work
	if (!test_equality(mysqlpp::String("123.00"), 123)) return false;
	if (!test_equality(mysqlpp::String("123."), 123)) return false;

	// This is trickier: MySQL ignores the system locale when it comes
	// to decimal separators, always using '.', so ensure the conversion
	// stuff in MySQL++ does the right thing regardless.  Test against
	// this system's current locale, an arbitrary European one where ','
	// is the decimal separator, and the "C" locale where it's '.'.
	if (!test_equality(mysqlpp::String("621.200"), 621.2)) return false;
	std::locale old_locale = std::locale::global(std::locale::classic());
	if (!test_equality(mysqlpp::String("621.200"), 621.2)) return false;
	std::locale::global(std::locale("de_DE"));
	if (!test_equality(mysqlpp::String("621.200"), 621.2)) return false;
	std::locale::global(old_locale);

	// Check that we choke on silly float-like values
	try {
		if (test_equality(mysqlpp::String("621.20.0"), 621.2)) {
			std::cerr << "Quasi-FP with two decimal points "
					"converting without error!" << std::endl;
		}
		return false;
	}
	catch (const mysqlpp::BadConversion&) {
		return true;
	}
}

// Tries to convert the given string to an int.  Returns false if we got
// a BadConversion exception and didn't expect it, or didn't get one we
// expected.  Returns false on all other exceptions regardless.
static bool
test_int_conversion(const mysqlpp::String& s, bool throw_expected)
{
	// Try the conversion
	bool conv_threw = false;
	try {
		int converted = s;
	}
	catch (const mysqlpp::BadConversion&) {
		conv_threw = true;
	}
	catch (const std::exception& e) {
		std::cerr << "Unexpected " << typeid(e).name() <<
				" exception in test_int_conv: " << e.what() << std::endl;
		return false;
	}
	catch (...) {
		std::cerr << "Like, totally bogus exception in test_int_conv, "
				"man!" << std::endl;
		return false;
	}

	// Did it do what we expected?
	if (throw_expected == conv_threw) {
		return true;
	}
	else {
		std::cerr << "Conversion of \"" << s << "\" to int " <<
				(conv_threw ? "did not " : "") << "throw; did " <<
				(throw_expected ? "not " : "") << "expect it to." <<
				std::endl;
		return false;
	}
}

// Ensures that the program's locale doesn't affect our floating-point
// conversions.  ('.' vs. ',' stuff.)
static bool
test_locale()
{

	return true;
}

// Ensures numeric conversions of many different types get handled
// correctly.
static bool
test_numeric(const mysqlpp::String& s, int value)
{
	return	test_equality(s, static_cast<signed char>(value)) &&
			test_equality(s, static_cast<unsigned char>(value)) &&
			test_equality(s, static_cast<signed short>(value)) &&
			test_equality(s, static_cast<unsigned short>(value)) &&
			test_equality(s, static_cast<signed int>(value)) &&
			test_equality(s, static_cast<unsigned int>(value)) &&
			test_equality(s, static_cast<signed long>(value)) &&
			test_equality(s, static_cast<unsigned long>(value)) &&
#if !defined(NO_LONG_LONGS)
			test_equality(s, static_cast<mysqlpp::longlong>(value)) &&
			test_equality(s, static_cast<mysqlpp::ulonglong>(value)) &&
#endif
			test_equality(s, static_cast<float>(value)) &&
			test_equality(s, static_cast<double>(value));
}

static bool
test_quote_q(const mysqlpp::String& s, bool expected)
{
	if (s.quote_q() == expected) {
		return true;
	}
	else {
		std::cerr << s.type().name() << " should" <<
				(expected ? "" : " NOT") << " be quoted." << std::endl;
		return false;
	}
}

int
main(int, char* argv[])
{
	try {
		int failures = 0;
		mysqlpp::String empty;
		mysqlpp::String zero("0");
		mysqlpp::String nonzero("42");

		failures += test_equality(empty, mysqlpp::Date()) == false;
		failures += test_equality(empty,
				mysqlpp::DateTime(0, 0, 0, 0, 0, 0)) == false;
		failures += test_equality(empty, mysqlpp::Time()) == false;
		failures += test_equality(empty, false) == false;
		failures += test_equality(nonzero, true) == false;
		failures += test_numeric(empty, 0) == false;
		failures += test_numeric(zero, 0) == false;
		failures += test_numeric(nonzero, 42) == false;
		failures += test_quote_q(empty, true) == false;
		failures += test_quote_q(mysqlpp::String("1", typeid(int)),
				false) == false;
		failures += test_locale() == false;
		failures += test_float_conversion() == false;
		failures += test_float_conversion() == false;

		return failures;
	}
	catch (mysqlpp::Exception& e) {
		std::cerr << "Unexpected MySQL++ exception caught in " <<
				argv[0] << ": " << e.what() << std::endl;
		return 1;
	}
	catch (std::exception& e) {
		std::cerr << "Unexpected C++ exception caught in " <<
				argv[0] << ": " << e.what() << std::endl;
		return 1;
	}

}

<commit_msg>Squished a pedantic GCC warning<commit_after>/***********************************************************************
 test/string.cpp - Tests the behavior of mysqlpp::String, particularly
	its data conversion methods.

 Copyright (c) 2007-2008 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the
 CREDITS file in the top directory of the distribution for details.

 This file is part of MySQL++.

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

 MySQL++ 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 MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#include <mysql++.h>

#include <iostream>

// Does an equality comparison on the value, forcing the string to
// convert itself to T on the way.  Note that we do this test in terms
// of greater and less than to avoid pedantic GCC warnings for the
// floating point type tests.
template <typename T>
static bool
test_equality(const mysqlpp::String& s, T value)
{
	T converted = s.conv(value);
	if ((value < converted) || (value > converted)) {
		std::cerr << "Type conversion to " << typeid(T).name() <<
				" failed: \"" << s << "\" != \"" << value << "\"." <<
				std::endl;
		return false;
	}
	else {
		return true;
	}
}

// Check that we can convert strings with decimals in them to native
// floating-point values, regardless of locale.
static bool
test_float_conversion()
{
	// This stuff should just work
	if (!test_equality(mysqlpp::String("123.00"), 123)) return false;
	if (!test_equality(mysqlpp::String("123."), 123)) return false;

	// This is trickier: MySQL ignores the system locale when it comes
	// to decimal separators, always using '.', so ensure the conversion
	// stuff in MySQL++ does the right thing regardless.  Test against
	// this system's current locale, an arbitrary European one where ','
	// is the decimal separator, and the "C" locale where it's '.'.
	if (!test_equality(mysqlpp::String("621.200"), 621.2)) return false;
	std::locale old_locale = std::locale::global(std::locale::classic());
	if (!test_equality(mysqlpp::String("621.200"), 621.2)) return false;
	std::locale::global(std::locale("de_DE"));
	if (!test_equality(mysqlpp::String("621.200"), 621.2)) return false;
	std::locale::global(old_locale);

	// Check that we choke on silly float-like values
	try {
		if (test_equality(mysqlpp::String("621.20.0"), 621.2)) {
			std::cerr << "Quasi-FP with two decimal points "
					"converting without error!" << std::endl;
		}
		return false;
	}
	catch (const mysqlpp::BadConversion&) {
		return true;
	}
}

// Tries to convert the given string to an int.  Returns false if we got
// a BadConversion exception and didn't expect it, or didn't get one we
// expected.  Returns false on all other exceptions regardless.
static bool
test_int_conversion(const mysqlpp::String& s, bool throw_expected)
{
	// Try the conversion
	bool conv_threw = false;
	try {
		int converted = s;
		(void)converted;	// pedantic warning squisher
	}
	catch (const mysqlpp::BadConversion&) {
		conv_threw = true;
	}
	catch (const std::exception& e) {
		std::cerr << "Unexpected " << typeid(e).name() <<
				" exception in test_int_conv: " << e.what() << std::endl;
		return false;
	}
	catch (...) {
		std::cerr << "Like, totally bogus exception in test_int_conv, "
				"man!" << std::endl;
		return false;
	}

	// Did it do what we expected?
	if (throw_expected == conv_threw) {
		return true;
	}
	else {
		std::cerr << "Conversion of \"" << s << "\" to int " <<
				(conv_threw ? "did not " : "") << "throw; did " <<
				(throw_expected ? "not " : "") << "expect it to." <<
				std::endl;
		return false;
	}
}

// Ensures that the program's locale doesn't affect our floating-point
// conversions.  ('.' vs. ',' stuff.)
static bool
test_locale()
{

	return true;
}

// Ensures numeric conversions of many different types get handled
// correctly.
static bool
test_numeric(const mysqlpp::String& s, int value)
{
	return	test_equality(s, static_cast<signed char>(value)) &&
			test_equality(s, static_cast<unsigned char>(value)) &&
			test_equality(s, static_cast<signed short>(value)) &&
			test_equality(s, static_cast<unsigned short>(value)) &&
			test_equality(s, static_cast<signed int>(value)) &&
			test_equality(s, static_cast<unsigned int>(value)) &&
			test_equality(s, static_cast<signed long>(value)) &&
			test_equality(s, static_cast<unsigned long>(value)) &&
#if !defined(NO_LONG_LONGS)
			test_equality(s, static_cast<mysqlpp::longlong>(value)) &&
			test_equality(s, static_cast<mysqlpp::ulonglong>(value)) &&
#endif
			test_equality(s, static_cast<float>(value)) &&
			test_equality(s, static_cast<double>(value));
}

static bool
test_quote_q(const mysqlpp::String& s, bool expected)
{
	if (s.quote_q() == expected) {
		return true;
	}
	else {
		std::cerr << s.type().name() << " should" <<
				(expected ? "" : " NOT") << " be quoted." << std::endl;
		return false;
	}
}

int
main(int, char* argv[])
{
	try {
		int failures = 0;
		mysqlpp::String empty;
		mysqlpp::String zero("0");
		mysqlpp::String nonzero("42");

		failures += test_equality(empty, mysqlpp::Date()) == false;
		failures += test_equality(empty,
				mysqlpp::DateTime(0, 0, 0, 0, 0, 0)) == false;
		failures += test_equality(empty, mysqlpp::Time()) == false;
		failures += test_equality(empty, false) == false;
		failures += test_equality(nonzero, true) == false;
		failures += test_numeric(empty, 0) == false;
		failures += test_numeric(zero, 0) == false;
		failures += test_numeric(nonzero, 42) == false;
		failures += test_quote_q(empty, true) == false;
		failures += test_quote_q(mysqlpp::String("1", typeid(int)),
				false) == false;
		failures += test_locale() == false;
		failures += test_float_conversion() == false;
		failures += test_float_conversion() == false;

		return failures;
	}
	catch (mysqlpp::Exception& e) {
		std::cerr << "Unexpected MySQL++ exception caught in " <<
				argv[0] << ": " << e.what() << std::endl;
		return 1;
	}
	catch (std::exception& e) {
		std::cerr << "Unexpected C++ exception caught in " <<
				argv[0] << ": " << e.what() << std::endl;
		return 1;
	}

}

<|endoftext|>