<commit_before>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

///////////////////////////////////////////////////////////////////////////////
//                                                                           //
// TRD tender: reapply pid on the fly                                        //
//                                                                           //
///////////////////////////////////////////////////////////////////////////////

#include <TChain.h>
#include <TList.h>
#include <TObjString.h>
#include <TTree.h>
#include <TString.h>

#include <AliCDBEntry.h>
#include <AliCDBId.h>
#include <AliCDBManager.h>
#include <AliTRDCalDet.h>

#include <AliLog.h>
#include <TTree.h>
#include <TChain.h>
#include <AliPID.h>
#include <AliVEvent.h>
#include <AliESDEvent.h>
#include <AliESDpid.h>
#include <AliESDtrack.h>
#include <AliESDInputHandler.h>
#include <AliAnalysisManager.h>
#include <AliTRDPIDResponse.h>
#include <AliTender.h>

#include "AliTRDTenderSupply.h"

ClassImp(AliTRDTenderSupply)

//_____________________________________________________
AliTRDTenderSupply::AliTRDTenderSupply() :
  AliTenderSupply(),
  fESD(NULL),
  fESDpid(NULL),
  fChamberGainOld(NULL),
  fChamberGainNew(NULL),
  fChamberVdriftOld(NULL),
  fChamberVdriftNew(NULL),
  fFileNNref(""),
  fPIDmethod(kNNpid),
  fPthreshold(0.8),
  fNBadChambers(0),
  fGainCorrection(kTRUE)
{
  //
  // default ctor
  //
}

//_____________________________________________________
AliTRDTenderSupply::AliTRDTenderSupply(const char *name, const AliTender *tender) :
  AliTenderSupply(name,tender),
  fESD(NULL),
  fESDpid(NULL),
  fChamberGainOld(NULL),
  fChamberGainNew(NULL),
  fChamberVdriftOld(NULL),
  fChamberVdriftNew(NULL),
  fFileNNref(""),
  fPIDmethod(kNNpid),
  fPthreshold(0.8),
  fNBadChambers(0),
  fGainCorrection(kTRUE)
{
  //
  // named ctor
  //
  memset(fBadChamberID, 0, sizeof(Int_t) * kNChambers);
}

//_____________________________________________________
AliTRDTenderSupply::~AliTRDTenderSupply()
{
  //
  // dtor
  //
}

//_____________________________________________________
void AliTRDTenderSupply::Init()
{
  //
  // Initialise TRD tender
  //

  AliAnalysisManager *mgr=AliAnalysisManager::GetAnalysisManager();

  // 1DLQ PID implemented in the AliESD object
  fESDpid=fTender->GetESDhandler()->GetESDpid();
  if (!fESDpid) {
    fESDpid=new AliESDpid;
    fTender->GetESDhandler()->SetESDpid(fESDpid);
  }
  // Set Normalisation Factors
  if(mgr->GetMCtruthEventHandler()){
    // Assume MC
    //fESDpid->GetTRDResponse().SetGainNormalisationFactor(1.);
    SwitchOffGainCorrection();
  }
  else{
    // Assume Data
    //if(fPIDmethod == kNNpid) fPidRecal->SetGainScaleFactor(1.14);
    //fESDpid->GetTRDResponse().SetGainNormalisationFactor(1.14);
    SwitchOnGainCorrection();
  }
}

//_____________________________________________________
void AliTRDTenderSupply::ProcessEvent()
{
  //
  // Reapply pid information
  //
  if (fTender->RunChanged()){
    AliDebug(0, Form("AliTPCTenderSupply::ProcessEvent - Run Changed (%d)\n",fTender->GetRun()));
    if (fGainCorrection) SetChamberGain();
  }

  fESD = fTender->GetEvent();
  if (!fESD) return;
  Int_t ntracks=fESD->GetNumberOfTracks();

  //
  // recalculate PID probabilities
  //
  for(Int_t itrack = 0; itrack < ntracks; itrack++){
    AliESDtrack *track=fESD->GetTrack(itrack);
    // Recalculate likelihoods
    if(!(track->GetStatus() & AliESDtrack::kTRDout)) continue;
    if(fGainCorrection) ApplyGainCorrection(track);
    switch(fPIDmethod){
      case kNNpid:
        break;
      case k1DLQpid:
        fESDpid->MakeTRDPID(fESD->GetTrack(itrack));
        break;
      default:
        AliError("PID Method not implemented (yet)");
    }
  }
}

//_____________________________________________________
void AliTRDTenderSupply::SetChamberGain(){
  //
  // Load Chamber Gain factors into the Tender supply
  //

  //find previous entry from the UserInfo
  //   TTree *tree=((TChain*)fTender->GetInputData(0))->GetTree();
  AliAnalysisManager*mgr = AliAnalysisManager::GetAnalysisManager();
  AliAnalysisTaskSE *task = (AliAnalysisTaskSE*)mgr->GetTasks()->First();
  TTree *tree=((TChain*)task->GetInputData(0))->GetTree();
  if (!tree) {
  AliError("Tree not found in ESDhandler");
    return;
  }

  TList *userInfo=(TList*)tree->GetUserInfo();
  if (!userInfo) {
    AliError("No UserInfo found in tree");
    return;
  }

  TList *cdbList=(TList*)userInfo->FindObject("cdbList");
  if (!cdbList) {
    AliError("No cdbList found in UserInfo");
    if (AliLog::GetGlobalLogLevel()>=AliLog::kError) userInfo->Print();
    return;
  }

  TIter nextCDB(cdbList);
  TObjString *os=0x0;
  while ( (os=(TObjString*)nextCDB()) ){
    if(os->GetString().Contains("TRD/Calib/ChamberGainFactor")){
      // Get Old gain calibration
      AliCDBId *id=AliCDBId::MakeFromString(os->GetString());

      AliCDBEntry *entry=fTender->GetCDBManager()->Get(id->GetPath(), id->GetFirstRun(), id->GetVersion());
      if (!entry) {
        AliError("No previous gain calibration entry found");
        return;
      }

      fChamberGainOld = dynamic_cast<AliTRDCalDet *>(entry->GetObject());

      AliDebug(1, Form("Used old Gain entry: %s\n",entry->GetId().ToString().Data()));
    } else if(os->GetString().Contains("TRD/Calib/ChamberVdrift")){
      // Get Old drift velocity calibration
      AliCDBId *id=AliCDBId::MakeFromString(os->GetString());

      AliCDBEntry *entry=fTender->GetCDBManager()->Get(id->GetPath(), id->GetFirstRun(), id->GetVersion());
      if (!entry) {
        AliError("No previous drift velocity calibration entry found");
        return;
      }

      fChamberVdriftOld = dynamic_cast<AliTRDCalDet *>(entry->GetObject());

      AliDebug(1, Form("Used old Drift velocity entry: %s\n",entry->GetId().ToString().Data()));

    }
  }

  // Get Latest Gain Calib Object
  AliCDBEntry *entryNew=fTender->GetCDBManager()->Get("TRD/Calib/ChamberGainFactor",fTender->GetRun());
  if (entryNew) {
    AliDebug(1, Form("Used new Gain entry: %s\n",entryNew->GetId().ToString().Data()));
    fChamberGainNew = dynamic_cast<AliTRDCalDet *>(entryNew->GetObject());
  } else
    AliError("No new gain calibration entry found");

  // Also get the latest Drift Velocity calibration object
  entryNew=fTender->GetCDBManager()->Get("TRD/Calib/ChamberVdrift",fTender->GetRun());
  if (entryNew) {
    AliDebug(1, Form("Used new Drift velocity entry: %s\n",entryNew->GetId().ToString().Data()));
    fChamberVdriftNew = dynamic_cast<AliTRDCalDet *>(entryNew->GetObject());
  } else
    AliError("No new drift velocity calibration entry found");

  if(!fChamberGainNew || !fChamberVdriftNew) AliError("No recent calibration found");
}

//_____________________________________________________
void AliTRDTenderSupply::ApplyGainCorrection(AliESDtrack * track){
  //
  // Apply new gain factors to the track
  //
  if(!fChamberGainNew || !fChamberGainOld){
    AliError("Cannot apply gain correction.");
    return;
  }

  if(!(track->GetStatus() & AliESDtrack::kTRDout)) return;
  Double_t p = track->GetOuterParam() ? track->GetOuterParam()->P() : track->P();
  if(p < fPthreshold) return; // Apply low momentum cutoff

  Bool_t applyCorrectionVdrift = kFALSE;
  if(fChamberVdriftOld && fChamberVdriftNew) applyCorrectionVdrift = kTRUE;

  Int_t chamberID[kNPlanes];
  for(Int_t il = 0; il < kNPlanes; il++) chamberID[il] = -1;
  if(!GetTRDchamberID(track, chamberID)) return;
  Int_t nTrackletsPID = 0, nTracklets = track->GetTRDntracklets();
  for(Int_t iplane = 0; iplane < kNPlanes; iplane++){
    if(chamberID[iplane] < 0) continue;

    // Mask out bad chambers
    Bool_t isMasked = kFALSE;
    for(UInt_t icam = 0; icam < fNBadChambers; icam++)
      if(fBadChamberID[icam] == chamberID[iplane]){
        isMasked = kTRUE;
        break;
      }
    if(isMasked){
      for(Int_t islice = 0; islice < track->GetNumberOfTRDslices(); islice++){
        track->SetTRDslice(0, iplane, islice);
      }
      continue;
    }

    // Take old and new gain factor and make ratio
    Double_t facOld = fChamberGainOld->GetValue(chamberID[iplane]);
    Double_t facNew = fChamberGainNew->GetValue(chamberID[iplane]);
    Double_t correction = facNew/facOld;
    if(applyCorrectionVdrift){
      // apply also correction for drift velocity calibration
      Double_t vDriftOld = fChamberVdriftOld->GetValue(chamberID[iplane]);
      Double_t vDriftNew = fChamberVdriftNew->GetValue(chamberID[iplane]);
      correction *= vDriftNew/vDriftOld;
    }
    AliDebug(2, Form("Applying correction factor %f\n", correction));
    Int_t nSlices = 0;
    for(Int_t islice = 0; islice < track->GetNumberOfTRDslices(); islice++){
      Double_t qslice = track->GetTRDslice(iplane, islice);
      if(qslice <= 0.) continue;
      track->SetTRDslice(qslice / correction, iplane, islice);
      nSlices++;
    }
    if(nSlices) nTrackletsPID++;
  }
  // Use nTrackletsPID to indicate the number of tracklets from good
  // chambers so they are used for the PID
  track->SetTRDntracklets(nTrackletsPID | (nTracklets << 3));
}

//_____________________________________________________
Bool_t AliTRDTenderSupply::GetTRDchamberID(AliESDtrack * const track, Int_t *detectors) {
  //
  // Calculate TRD chamber ID
  //
  Double_t xLayer[kNPlanes] = {300.2, 312.8, 325.4, 338., 350.6, 363.2};
  Double_t etamin[kNStacks] = {0.536, 0.157, -0.145, -0.527,-0.851};
  Double_t etamax[kNStacks] = {0.851, 0.527, 0.145, -0.157,-0.536};
  for(Int_t ily = 0; ily < kNPlanes; ily++) detectors[ily] = -1;

  const AliExternalTrackParam *trueparam = NULL;
  if(track->GetTPCInnerParam()) trueparam = track->GetTPCInnerParam();
  else if(track->GetOuterParam()) trueparam = track->GetOuterParam();
  else if(track->GetInnerParam()) trueparam = track->GetInnerParam();
  if(!trueparam){
    AliDebug(2, "No Track Params");
    return kFALSE;
  }

  AliExternalTrackParam workparam(*trueparam); // Do calculation on working Copy
  Double_t pos[3];
  Int_t nDet = 0;
  for(Int_t ily = 0; ily < kNPlanes; ily++){
    if(!workparam.PropagateTo(xLayer[ily], fESD->GetMagneticField())) {
      AliDebug(2, "Propagation failed");
      break;
    }
    workparam.GetXYZ(pos);
    Double_t trackAlpha = TMath::ATan2(pos[1], pos[0]);
    if(trackAlpha < 0) trackAlpha = 2 * TMath::Pi() + trackAlpha;
    Double_t secAlpha = 2 * TMath::Pi() / 18.;

    Int_t sector = static_cast<Int_t>(trackAlpha/secAlpha);
    Double_t etaTrack = track->Eta();
    Int_t stack = -1;
    for(Int_t istack = 0; istack < 5; istack++){
      if(etaTrack >= etamin[istack] && etaTrack <= etamax[istack]){
        stack = istack;
        break;
      }
    }
    if(stack < 0) {
      AliDebug(2, "Dead Area");
      continue;
    }

    detectors[ily] = sector * kNStacks * kNPlanes + stack * kNPlanes + ily;
    nDet++;
  }
  return nDet ? kTRUE : kFALSE;
}

<commit_msg>Coverity 15168 Initialisation fixed.<commit_after>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

///////////////////////////////////////////////////////////////////////////////
//                                                                           //
// TRD tender: reapply pid on the fly                                        //
//                                                                           //
///////////////////////////////////////////////////////////////////////////////

#include <TChain.h>
#include <TList.h>
#include <TObjString.h>
#include <TTree.h>
#include <TString.h>

#include <AliCDBEntry.h>
#include <AliCDBId.h>
#include <AliCDBManager.h>
#include <AliTRDCalDet.h>

#include <AliLog.h>
#include <TTree.h>
#include <TChain.h>
#include <AliPID.h>
#include <AliVEvent.h>
#include <AliESDEvent.h>
#include <AliESDpid.h>
#include <AliESDtrack.h>
#include <AliESDInputHandler.h>
#include <AliAnalysisManager.h>
#include <AliTRDPIDResponse.h>
#include <AliTender.h>

#include "AliTRDTenderSupply.h"

ClassImp(AliTRDTenderSupply)

//_____________________________________________________
AliTRDTenderSupply::AliTRDTenderSupply() :
  AliTenderSupply(),
  fESD(NULL),
  fESDpid(NULL),
  fChamberGainOld(NULL),
  fChamberGainNew(NULL),
  fChamberVdriftOld(NULL),
  fChamberVdriftNew(NULL),
  fFileNNref(""),
  fPIDmethod(kNNpid),
  fPthreshold(0.8),
  fNBadChambers(0),
  fGainCorrection(kTRUE)
{
  //
  // default ctor
  //
  memset(fBadChamberID, 0, sizeof(Int_t) * kNChambers);
}

//_____________________________________________________
AliTRDTenderSupply::AliTRDTenderSupply(const char *name, const AliTender *tender) :
  AliTenderSupply(name,tender),
  fESD(NULL),
  fESDpid(NULL),
  fChamberGainOld(NULL),
  fChamberGainNew(NULL),
  fChamberVdriftOld(NULL),
  fChamberVdriftNew(NULL),
  fFileNNref(""),
  fPIDmethod(kNNpid),
  fPthreshold(0.8),
  fNBadChambers(0),
  fGainCorrection(kTRUE)
{
  //
  // named ctor
  //
  memset(fBadChamberID, 0, sizeof(Int_t) * kNChambers);
}

//_____________________________________________________
AliTRDTenderSupply::~AliTRDTenderSupply()
{
  //
  // dtor
  //
}

//_____________________________________________________
void AliTRDTenderSupply::Init()
{
  //
  // Initialise TRD tender
  //

  AliAnalysisManager *mgr=AliAnalysisManager::GetAnalysisManager();

  // 1DLQ PID implemented in the AliESD object
  fESDpid=fTender->GetESDhandler()->GetESDpid();
  if (!fESDpid) {
    fESDpid=new AliESDpid;
    fTender->GetESDhandler()->SetESDpid(fESDpid);
  }
  // Set Normalisation Factors
  if(mgr->GetMCtruthEventHandler()){
    // Assume MC
    //fESDpid->GetTRDResponse().SetGainNormalisationFactor(1.);
    SwitchOffGainCorrection();
  }
  else{
    // Assume Data
    //if(fPIDmethod == kNNpid) fPidRecal->SetGainScaleFactor(1.14);
    //fESDpid->GetTRDResponse().SetGainNormalisationFactor(1.14);
    SwitchOnGainCorrection();
  }
}

//_____________________________________________________
void AliTRDTenderSupply::ProcessEvent()
{
  //
  // Reapply pid information
  //
  if (fTender->RunChanged()){
    AliDebug(0, Form("AliTPCTenderSupply::ProcessEvent - Run Changed (%d)\n",fTender->GetRun()));
    if (fGainCorrection) SetChamberGain();
  }

  fESD = fTender->GetEvent();
  if (!fESD) return;
  Int_t ntracks=fESD->GetNumberOfTracks();

  //
  // recalculate PID probabilities
  //
  for(Int_t itrack = 0; itrack < ntracks; itrack++){
    AliESDtrack *track=fESD->GetTrack(itrack);
    // Recalculate likelihoods
    if(!(track->GetStatus() & AliESDtrack::kTRDout)) continue;
    if(fGainCorrection) ApplyGainCorrection(track);
    switch(fPIDmethod){
      case kNNpid:
        break;
      case k1DLQpid:
        fESDpid->MakeTRDPID(fESD->GetTrack(itrack));
        break;
      default:
        AliError("PID Method not implemented (yet)");
    }
  }
}

//_____________________________________________________
void AliTRDTenderSupply::SetChamberGain(){
  //
  // Load Chamber Gain factors into the Tender supply
  //

  //find previous entry from the UserInfo
  //   TTree *tree=((TChain*)fTender->GetInputData(0))->GetTree();
  AliAnalysisManager*mgr = AliAnalysisManager::GetAnalysisManager();
  AliAnalysisTaskSE *task = (AliAnalysisTaskSE*)mgr->GetTasks()->First();
  TTree *tree=((TChain*)task->GetInputData(0))->GetTree();
  if (!tree) {
  AliError("Tree not found in ESDhandler");
    return;
  }

  TList *userInfo=(TList*)tree->GetUserInfo();
  if (!userInfo) {
    AliError("No UserInfo found in tree");
    return;
  }

  TList *cdbList=(TList*)userInfo->FindObject("cdbList");
  if (!cdbList) {
    AliError("No cdbList found in UserInfo");
    if (AliLog::GetGlobalLogLevel()>=AliLog::kError) userInfo->Print();
    return;
  }

  TIter nextCDB(cdbList);
  TObjString *os=0x0;
  while ( (os=(TObjString*)nextCDB()) ){
    if(os->GetString().Contains("TRD/Calib/ChamberGainFactor")){
      // Get Old gain calibration
      AliCDBId *id=AliCDBId::MakeFromString(os->GetString());

      AliCDBEntry *entry=fTender->GetCDBManager()->Get(id->GetPath(), id->GetFirstRun(), id->GetVersion());
      if (!entry) {
        AliError("No previous gain calibration entry found");
        return;
      }

      fChamberGainOld = dynamic_cast<AliTRDCalDet *>(entry->GetObject());

      AliDebug(1, Form("Used old Gain entry: %s\n",entry->GetId().ToString().Data()));
    } else if(os->GetString().Contains("TRD/Calib/ChamberVdrift")){
      // Get Old drift velocity calibration
      AliCDBId *id=AliCDBId::MakeFromString(os->GetString());

      AliCDBEntry *entry=fTender->GetCDBManager()->Get(id->GetPath(), id->GetFirstRun(), id->GetVersion());
      if (!entry) {
        AliError("No previous drift velocity calibration entry found");
        return;
      }

      fChamberVdriftOld = dynamic_cast<AliTRDCalDet *>(entry->GetObject());

      AliDebug(1, Form("Used old Drift velocity entry: %s\n",entry->GetId().ToString().Data()));

    }
  }

  // Get Latest Gain Calib Object
  AliCDBEntry *entryNew=fTender->GetCDBManager()->Get("TRD/Calib/ChamberGainFactor",fTender->GetRun());
  if (entryNew) {
    AliDebug(1, Form("Used new Gain entry: %s\n",entryNew->GetId().ToString().Data()));
    fChamberGainNew = dynamic_cast<AliTRDCalDet *>(entryNew->GetObject());
  } else
    AliError("No new gain calibration entry found");

  // Also get the latest Drift Velocity calibration object
  entryNew=fTender->GetCDBManager()->Get("TRD/Calib/ChamberVdrift",fTender->GetRun());
  if (entryNew) {
    AliDebug(1, Form("Used new Drift velocity entry: %s\n",entryNew->GetId().ToString().Data()));
    fChamberVdriftNew = dynamic_cast<AliTRDCalDet *>(entryNew->GetObject());
  } else
    AliError("No new drift velocity calibration entry found");

  if(!fChamberGainNew || !fChamberVdriftNew) AliError("No recent calibration found");
}

//_____________________________________________________
void AliTRDTenderSupply::ApplyGainCorrection(AliESDtrack * track){
  //
  // Apply new gain factors to the track
  //
  if(!fChamberGainNew || !fChamberGainOld){
    AliError("Cannot apply gain correction.");
    return;
  }

  if(!(track->GetStatus() & AliESDtrack::kTRDout)) return;
  Double_t p = track->GetOuterParam() ? track->GetOuterParam()->P() : track->P();
  if(p < fPthreshold) return; // Apply low momentum cutoff

  Bool_t applyCorrectionVdrift = kFALSE;
  if(fChamberVdriftOld && fChamberVdriftNew) applyCorrectionVdrift = kTRUE;

  Int_t chamberID[kNPlanes];
  for(Int_t il = 0; il < kNPlanes; il++) chamberID[il] = -1;
  if(!GetTRDchamberID(track, chamberID)) return;
  Int_t nTrackletsPID = 0, nTracklets = track->GetTRDntracklets();
  for(Int_t iplane = 0; iplane < kNPlanes; iplane++){
    if(chamberID[iplane] < 0) continue;

    // Mask out bad chambers
    Bool_t isMasked = kFALSE;
    for(UInt_t icam = 0; icam < fNBadChambers; icam++)
      if(fBadChamberID[icam] == chamberID[iplane]){
        isMasked = kTRUE;
        break;
      }
    if(isMasked){
      for(Int_t islice = 0; islice < track->GetNumberOfTRDslices(); islice++){
        track->SetTRDslice(0, iplane, islice);
      }
      continue;
    }

    // Take old and new gain factor and make ratio
    Double_t facOld = fChamberGainOld->GetValue(chamberID[iplane]);
    Double_t facNew = fChamberGainNew->GetValue(chamberID[iplane]);
    Double_t correction = facNew/facOld;
    if(applyCorrectionVdrift){
      // apply also correction for drift velocity calibration
      Double_t vDriftOld = fChamberVdriftOld->GetValue(chamberID[iplane]);
      Double_t vDriftNew = fChamberVdriftNew->GetValue(chamberID[iplane]);
      correction *= vDriftNew/vDriftOld;
    }
    AliDebug(2, Form("Applying correction factor %f\n", correction));
    Int_t nSlices = 0;
    for(Int_t islice = 0; islice < track->GetNumberOfTRDslices(); islice++){
      Double_t qslice = track->GetTRDslice(iplane, islice);
      if(qslice <= 0.) continue;
      track->SetTRDslice(qslice / correction, iplane, islice);
      nSlices++;
    }
    if(nSlices) nTrackletsPID++;
  }
  // Use nTrackletsPID to indicate the number of tracklets from good
  // chambers so they are used for the PID
  track->SetTRDntracklets(nTrackletsPID | (nTracklets << 3));
}

//_____________________________________________________
Bool_t AliTRDTenderSupply::GetTRDchamberID(AliESDtrack * const track, Int_t *detectors) {
  //
  // Calculate TRD chamber ID
  //
  Double_t xLayer[kNPlanes] = {300.2, 312.8, 325.4, 338., 350.6, 363.2};
  Double_t etamin[kNStacks] = {0.536, 0.157, -0.145, -0.527,-0.851};
  Double_t etamax[kNStacks] = {0.851, 0.527, 0.145, -0.157,-0.536};
  for(Int_t ily = 0; ily < kNPlanes; ily++) detectors[ily] = -1;

  const AliExternalTrackParam *trueparam = NULL;
  if(track->GetTPCInnerParam()) trueparam = track->GetTPCInnerParam();
  else if(track->GetOuterParam()) trueparam = track->GetOuterParam();
  else if(track->GetInnerParam()) trueparam = track->GetInnerParam();
  if(!trueparam){
    AliDebug(2, "No Track Params");
    return kFALSE;
  }

  AliExternalTrackParam workparam(*trueparam); // Do calculation on working Copy
  Double_t pos[3];
  Int_t nDet = 0;
  for(Int_t ily = 0; ily < kNPlanes; ily++){
    if(!workparam.PropagateTo(xLayer[ily], fESD->GetMagneticField())) {
      AliDebug(2, "Propagation failed");
      break;
    }
    workparam.GetXYZ(pos);
    Double_t trackAlpha = TMath::ATan2(pos[1], pos[0]);
    if(trackAlpha < 0) trackAlpha = 2 * TMath::Pi() + trackAlpha;
    Double_t secAlpha = 2 * TMath::Pi() / 18.;

    Int_t sector = static_cast<Int_t>(trackAlpha/secAlpha);
    Double_t etaTrack = track->Eta();
    Int_t stack = -1;
    for(Int_t istack = 0; istack < 5; istack++){
      if(etaTrack >= etamin[istack] && etaTrack <= etamax[istack]){
        stack = istack;
        break;
      }
    }
    if(stack < 0) {
      AliDebug(2, "Dead Area");
      continue;
    }

    detectors[ily] = sector * kNStacks * kNPlanes + stack * kNPlanes + ily;
    nDet++;
  }
  return nDet ? kTRUE : kFALSE;
}

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: groupupdate.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 03:15:00 $
 *
 *  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 CONFIGMGR_API_GROUPUPDATE_HXX_
#define CONFIGMGR_API_GROUPUPDATE_HXX_

#include "groupaccess.hxx"

#ifndef _COM_SUN_STAR_CONTAINER_XNAMEREPLACE_HPP_
#include <com/sun/star/container/XNameReplace.hpp>
#endif

//........................................................................
namespace configmgr
{
//........................................................................
    namespace configapi { class NodeGroupAccess; }

//==========================================================================
//= BasicGroup
//==========================================================================

/** base class for configuration nodes which are dynamic sets of complex types (trees)
*/
    class BasicGroup
    : public BasicGroupAccess
    , public css::container::XNameReplace
    {
    protected:
    // Destructors
        virtual ~BasicGroup() {}

    public:
    // Base class Interface methods
        // XInterface joining
        uno::Any SAL_CALL queryInterface( uno::Type const& rType ) throw (uno::RuntimeException );

        // XTypeProvider joining
        uno::Sequence< uno::Type > SAL_CALL getTypes( ) throw (uno::RuntimeException );
        uno::Sequence< sal_Int8 > SAL_CALL getImplementationId( ) throw (uno::RuntimeException ) = 0;

        // XElementAccess forwarding
        virtual uno::Type SAL_CALL getElementType(  ) throw(uno::RuntimeException)
        { return BasicGroupAccess::getElementType(); }

        virtual sal_Bool SAL_CALL hasElements(  )  throw(uno::RuntimeException)
        { return BasicGroupAccess::hasElements(); }

        // XNameAccess forwarding
        virtual uno::Any SAL_CALL getByName( const OUString& aName )
            throw(css::container::NoSuchElementException, css::lang::WrappedTargetException, uno::RuntimeException)
         { return BasicGroupAccess::getByName(aName); }

        virtual uno::Sequence< OUString > SAL_CALL getElementNames(  ) throw( uno::RuntimeException)
         { return BasicGroupAccess::getElementNames(); }

        virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) throw(uno::RuntimeException)
         { return BasicGroupAccess::hasByName(aName); }

    // New Interface methods
        // XNameReplace
        virtual void SAL_CALL
            replaceByName( const OUString& rName, const uno::Any& rElement )
                throw(css::lang::IllegalArgumentException, css::container::NoSuchElementException, css::lang::WrappedTargetException, uno::RuntimeException);

    protected:
                configapi::NodeGroupAccess& getGroupNode();
        virtual configapi::NodeGroupAccess* maybeGetUpdateAccess() = 0;
    };

//........................................................................
} // namespace configmgr
//........................................................................

#endif // CONFIGMGR_API_GROUPUPDATE_HXX_

<commit_msg>INTEGRATION: CWS changefileheader (1.3.130); FILE MERGED 2008/04/01 12:27:12 thb 1.3.130.2: #i85898# Stripping all external header guards 2008/03/31 12:22:37 rt 1.3.130.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: groupupdate.hxx,v $
 * $Revision: 1.4 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef CONFIGMGR_API_GROUPUPDATE_HXX_
#define CONFIGMGR_API_GROUPUPDATE_HXX_

#include "groupaccess.hxx"
#include <com/sun/star/container/XNameReplace.hpp>

//........................................................................
namespace configmgr
{
//........................................................................
    namespace configapi { class NodeGroupAccess; }

//==========================================================================
//= BasicGroup
//==========================================================================

/** base class for configuration nodes which are dynamic sets of complex types (trees)
*/
    class BasicGroup
    : public BasicGroupAccess
    , public css::container::XNameReplace
    {
    protected:
    // Destructors
        virtual ~BasicGroup() {}

    public:
    // Base class Interface methods
        // XInterface joining
        uno::Any SAL_CALL queryInterface( uno::Type const& rType ) throw (uno::RuntimeException );

        // XTypeProvider joining
        uno::Sequence< uno::Type > SAL_CALL getTypes( ) throw (uno::RuntimeException );
        uno::Sequence< sal_Int8 > SAL_CALL getImplementationId( ) throw (uno::RuntimeException ) = 0;

        // XElementAccess forwarding
        virtual uno::Type SAL_CALL getElementType(  ) throw(uno::RuntimeException)
        { return BasicGroupAccess::getElementType(); }

        virtual sal_Bool SAL_CALL hasElements(  )  throw(uno::RuntimeException)
        { return BasicGroupAccess::hasElements(); }

        // XNameAccess forwarding
        virtual uno::Any SAL_CALL getByName( const OUString& aName )
            throw(css::container::NoSuchElementException, css::lang::WrappedTargetException, uno::RuntimeException)
         { return BasicGroupAccess::getByName(aName); }

        virtual uno::Sequence< OUString > SAL_CALL getElementNames(  ) throw( uno::RuntimeException)
         { return BasicGroupAccess::getElementNames(); }

        virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) throw(uno::RuntimeException)
         { return BasicGroupAccess::hasByName(aName); }

    // New Interface methods
        // XNameReplace
        virtual void SAL_CALL
            replaceByName( const OUString& rName, const uno::Any& rElement )
                throw(css::lang::IllegalArgumentException, css::container::NoSuchElementException, css::lang::WrappedTargetException, uno::RuntimeException);

    protected:
                configapi::NodeGroupAccess& getGroupNode();
        virtual configapi::NodeGroupAccess* maybeGetUpdateAccess() = 0;
    };

//........................................................................
} // namespace configmgr
//........................................................................

#endif // CONFIGMGR_API_GROUPUPDATE_HXX_

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCS: $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: oj $ $Date: 2002-07-05 07:03:02 $
 *
 *  The Contents of this  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  are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the License); You may not use this
 *  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 CONNECTIVITY_TKEYVALUE_HXX
#define CONNECTIVITY_TKEYVALUE_HXX

#ifndef _CONNECTIVITY_FILE_VALUE_HXX_
#include "connectivity/FValue.hxx"
#endif

namespace connectivity
{
    class OKeyValue
    {
    private:
        ::std::vector<ORowSetValueDecoratorRef> m_aKeys;
        sal_Int32 m_nValue;

    protected:
        OKeyValue();
        OKeyValue(sal_Int32 nVal);
    public:

        ~OKeyValue();

        inline static void * SAL_CALL operator new( size_t nSize ) SAL_THROW( () )
            { return ::rtl_allocateMemory( nSize ); }
        inline static void * SAL_CALL operator new( size_t nSize,void* _pHint ) SAL_THROW( () )
            { return _pHint; }
        inline static void SAL_CALL operator delete( void * pMem ) SAL_THROW( () )
            { ::rtl_freeMemory( pMem ); }
        inline static void SAL_CALL operator delete( void * pMem,void* _pHint ) SAL_THROW( () )
            {  }

        static OKeyValue* createKeyValue(sal_Int32 nVal);
        //  static OKeyValue* createEmptyKeyValue();

        inline void pushKey(const ORowSetValueDecoratorRef& _aValueRef)
        {
            m_aKeys.push_back(_aValueRef);
        }
        inline void setValue(sal_Int32 nVal) { m_nValue = nVal; }

        ::rtl::OUString getKeyString(::std::vector<ORowSetValueDecoratorRef>::size_type i) const
        {
            OSL_ENSURE(m_aKeys.size() > i,"Wrong index for KEyValue");
            return m_aKeys[i]->getValue();
        }
        double          getKeyDouble(::std::vector<ORowSetValueDecoratorRef>::size_type i) const
        {
            OSL_ENSURE(m_aKeys.size() > i,"Wrong index for KEyValue");
            return m_aKeys[i]->getValue();
        }

        inline sal_Int32 getValue() const { return m_nValue; }
    };
}

#endif // CONNECTIVITY_TKEYVALUE_HXX

<commit_msg>INTEGRATION: CWS ooo19126 (1.4.326); FILE MERGED 2005/09/05 17:24:49 rt 1.4.326.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: TKeyValue.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 06:39:29 $
 *
 *  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 CONNECTIVITY_TKEYVALUE_HXX
#define CONNECTIVITY_TKEYVALUE_HXX

#ifndef _CONNECTIVITY_FILE_VALUE_HXX_
#include "connectivity/FValue.hxx"
#endif

namespace connectivity
{
    class OKeyValue
    {
    private:
        ::std::vector<ORowSetValueDecoratorRef> m_aKeys;
        sal_Int32 m_nValue;

    protected:
        OKeyValue();
        OKeyValue(sal_Int32 nVal);
    public:

        ~OKeyValue();

        inline static void * SAL_CALL operator new( size_t nSize ) SAL_THROW( () )
            { return ::rtl_allocateMemory( nSize ); }
        inline static void * SAL_CALL operator new( size_t nSize,void* _pHint ) SAL_THROW( () )
            { return _pHint; }
        inline static void SAL_CALL operator delete( void * pMem ) SAL_THROW( () )
            { ::rtl_freeMemory( pMem ); }
        inline static void SAL_CALL operator delete( void * pMem,void* _pHint ) SAL_THROW( () )
            {  }

        static OKeyValue* createKeyValue(sal_Int32 nVal);
        //  static OKeyValue* createEmptyKeyValue();

        inline void pushKey(const ORowSetValueDecoratorRef& _aValueRef)
        {
            m_aKeys.push_back(_aValueRef);
        }
        inline void setValue(sal_Int32 nVal) { m_nValue = nVal; }

        ::rtl::OUString getKeyString(::std::vector<ORowSetValueDecoratorRef>::size_type i) const
        {
            OSL_ENSURE(m_aKeys.size() > i,"Wrong index for KEyValue");
            return m_aKeys[i]->getValue();
        }
        double          getKeyDouble(::std::vector<ORowSetValueDecoratorRef>::size_type i) const
        {
            OSL_ENSURE(m_aKeys.size() > i,"Wrong index for KEyValue");
            return m_aKeys[i]->getValue();
        }

        inline sal_Int32 getValue() const { return m_nValue; }
    };
}

#endif // CONNECTIVITY_TKEYVALUE_HXX

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: VColumn.cxx,v $
 *
 *  $Revision: 1.14 $
 *
 *  last change: $Author: vg $ $Date: 2003-06-06 10:51:14 $
 *
 *  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 _CONNECTIVITY_SDBCX_COLUMN_HXX_
#include "connectivity/sdbcx/VColumn.hxx"
#endif
#ifndef _COM_SUN_STAR_LANG_DISPOSEDEXCEPTION_HPP_
#include <com/sun/star/lang/DisposedException.hpp>
#endif
#ifndef _COMPHELPER_SEQUENCE_HXX_
#include <comphelper/sequence.hxx>
#endif
#ifndef CONNECTIVITY_CONNECTION_HXX
#include "TConnection.hxx"
#endif
#ifndef _COM_SUN_STAR_SDBC_COLUMNVALUE_HPP_
#include <com/sun/star/sdbc/ColumnValue.hpp>
#endif
// -------------------------------------------------------------------------
using namespace connectivity;
using namespace connectivity::sdbcx;
using namespace cppu;
using namespace connectivity;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::sdbc;

// -----------------------------------------------------------------------------
::rtl::OUString SAL_CALL OColumn::getImplementationName(  ) throw (::com::sun::star::uno::RuntimeException)
{
    if(isNew())
        return ::rtl::OUString::createFromAscii("com.sun.star.sdbcx.VColumnDescription");
    return ::rtl::OUString::createFromAscii("com.sun.star.sdbcx.VColumn");
}
// -----------------------------------------------------------------------------
::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL OColumn::getSupportedServiceNames(  ) throw(::com::sun::star::uno::RuntimeException)
{
    ::com::sun::star::uno::Sequence< ::rtl::OUString > aSupported(1);
    if(isNew())
        aSupported[0] = ::rtl::OUString::createFromAscii("com.sun.star.sdbcx.ColumnDescription");
    else
        aSupported[0] = ::rtl::OUString::createFromAscii("com.sun.star.sdbcx.Column");

    return aSupported;
}
// -----------------------------------------------------------------------------
sal_Bool SAL_CALL OColumn::supportsService( const ::rtl::OUString& _rServiceName ) throw(::com::sun::star::uno::RuntimeException)
{
    Sequence< ::rtl::OUString > aSupported(getSupportedServiceNames());
    const ::rtl::OUString* pSupported = aSupported.getConstArray();
    const ::rtl::OUString* pEnd = pSupported + aSupported.getLength();
    for (;pSupported != pEnd && !pSupported->equals(_rServiceName); ++pSupported)
        ;

    return pSupported != pEnd;
}
// -------------------------------------------------------------------------
OColumn::OColumn(sal_Bool _bCase)  :    OColumnDescriptor_BASE(m_aMutex)
                    ,   ODescriptor(OColumnDescriptor_BASE::rBHelper,_bCase,sal_True)
                    ,   m_Precision(0)
                    ,   m_Type(0)
                    ,   m_Scale(0)
                    ,   m_IsNullable(ColumnValue::NULLABLE)
                    ,   m_IsAutoIncrement(sal_False)
                    ,   m_IsRowVersion(sal_False)
                    ,   m_IsCurrency(sal_False)
{
    construct();
}
// -------------------------------------------------------------------------
OColumn::OColumn(   const ::rtl::OUString& _Name,
                    const ::rtl::OUString& _TypeName,
                    const ::rtl::OUString& _DefaultValue,
                    sal_Int32       _IsNullable,
                    sal_Int32       _Precision,
                    sal_Int32       _Scale,
                    sal_Int32       _Type,
                    sal_Bool        _IsAutoIncrement,
                    sal_Bool        _IsRowVersion,
                    sal_Bool        _IsCurrency,
                    sal_Bool        _bCase)
            :   OColumnDescriptor_BASE(m_aMutex)
            ,   ODescriptor(OColumnDescriptor_BASE::rBHelper,_bCase)
            ,   m_TypeName(_TypeName)
            ,   m_DefaultValue(_DefaultValue)
            ,   m_Precision(_Precision)
            ,   m_Type(_Type)
            ,   m_Scale(_Scale)
            ,   m_IsNullable(_IsNullable)
            ,   m_IsAutoIncrement(_IsAutoIncrement)
            ,   m_IsRowVersion(_IsRowVersion)
            ,   m_IsCurrency(_IsCurrency)
{
    m_Name = _Name;

    construct();
}
// -------------------------------------------------------------------------
OColumn::~OColumn()
{
}
// -----------------------------------------------------------------------------
::cppu::IPropertyArrayHelper* OColumn::createArrayHelper( sal_Int32 _nId) const
{
    ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property > aProps;
    describeProperties(aProps);
    changePropertyAttributte(aProps);
    return new ::cppu::OPropertyArrayHelper(aProps);
}
// -----------------------------------------------------------------------------
::cppu::IPropertyArrayHelper& SAL_CALL OColumn::getInfoHelper()
{
    return *OColumn_PROP::getArrayHelper(isNew() ? 1 : 0);
}
// -----------------------------------------------------------------------------
void SAL_CALL OColumn::acquire() throw()
{
    OColumnDescriptor_BASE::acquire();
}
// -----------------------------------------------------------------------------
void SAL_CALL OColumn::release() throw()
{
    OColumnDescriptor_BASE::release();
}
// -----------------------------------------------------------------------------
Any SAL_CALL OColumn::queryInterface( const Type & rType ) throw(RuntimeException)
{
    Any aRet = ODescriptor::queryInterface( rType);
    if(!aRet.hasValue())
    {
        if(!isNew())
            aRet = OColumn_BASE::queryInterface(rType);
        if(!aRet.hasValue())
            aRet = OColumnDescriptor_BASE::queryInterface( rType);
    }
    return aRet;
}
// -------------------------------------------------------------------------
Sequence< Type > SAL_CALL OColumn::getTypes(  ) throw(RuntimeException)
{
    if(isNew())
        return ::comphelper::concatSequences(ODescriptor::getTypes(),OColumnDescriptor_BASE::getTypes());

    return ::comphelper::concatSequences(ODescriptor::getTypes(),OColumn_BASE::getTypes(),OColumnDescriptor_BASE::getTypes());
}
// -------------------------------------------------------------------------
void OColumn::construct()
{
    ODescriptor::construct();

    sal_Int32 nAttrib = isNew() ? 0 : PropertyAttribute::READONLY;

    registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPENAME),            PROPERTY_ID_TYPENAME,           nAttrib,&m_TypeName,        ::getCppuType(reinterpret_cast< ::rtl::OUString*>(NULL)));
    registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_DESCRIPTION),     PROPERTY_ID_DESCRIPTION,        nAttrib,&m_Description,     ::getCppuType(reinterpret_cast< ::rtl::OUString*>(NULL)));
    registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_DEFAULTVALUE),        PROPERTY_ID_DEFAULTVALUE,       nAttrib,&m_DefaultValue,    ::getCppuType(reinterpret_cast< ::rtl::OUString*>(NULL)));
    registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_PRECISION),       PROPERTY_ID_PRECISION,          nAttrib,&m_Precision,       ::getCppuType(reinterpret_cast<sal_Int32*>(NULL)));
    registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE),                PROPERTY_ID_TYPE,               nAttrib,&m_Type,            ::getCppuType(reinterpret_cast<sal_Int32*>(NULL)));
    registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_SCALE),           PROPERTY_ID_SCALE,              nAttrib,&m_Scale,           ::getCppuType(reinterpret_cast<sal_Int32*>(NULL)));
    registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ISNULLABLE),      PROPERTY_ID_ISNULLABLE,         nAttrib,&m_IsNullable,      ::getCppuType(reinterpret_cast<sal_Int32*>(NULL)));
    registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ISAUTOINCREMENT), PROPERTY_ID_ISAUTOINCREMENT,    nAttrib,&m_IsAutoIncrement, ::getBooleanCppuType());
    registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ISROWVERSION),        PROPERTY_ID_ISROWVERSION,       nAttrib,&m_IsRowVersion,    ::getBooleanCppuType());
    registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ISCURRENCY),      PROPERTY_ID_ISCURRENCY,         nAttrib,&m_IsCurrency,      ::getBooleanCppuType());
}
// -------------------------------------------------------------------------
void OColumn::disposing(void)
{
    OPropertySetHelper::disposing();

    ::osl::MutexGuard aGuard(m_aMutex);
    checkDisposed(OColumnDescriptor_BASE::rBHelper.bDisposed);

}
// -------------------------------------------------------------------------
Reference< XPropertySet > SAL_CALL OColumn::createDataDescriptor(  ) throw(RuntimeException)
{
    ::osl::MutexGuard aGuard(m_aMutex);
    checkDisposed(OColumnDescriptor_BASE::rBHelper.bDisposed);

    OColumn* pNewColumn = new OColumn(  m_Name,
                                        m_TypeName,
                                        m_DefaultValue,
                                        m_IsNullable,
                                        m_Precision,
                                        m_Scale,
                                        m_Type,
                                        m_IsAutoIncrement,
                                        m_IsRowVersion,
                                        m_IsCurrency,
                                        isCaseSensitive());
    pNewColumn->m_Description = m_Description;
    pNewColumn->setNew(sal_True);
    return pNewColumn;
}
// -----------------------------------------------------------------------------
::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL OColumn::getPropertySetInfo(  ) throw(::com::sun::star::uno::RuntimeException)
{
    return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper());
}
// -----------------------------------------------------------------------------
// XNamed
::rtl::OUString SAL_CALL OColumn::getName(  ) throw(::com::sun::star::uno::RuntimeException)
{
    return m_Name;
}
// -----------------------------------------------------------------------------
void SAL_CALL OColumn::setName( const ::rtl::OUString& aName ) throw(::com::sun::star::uno::RuntimeException)
{
    m_Name = aName;
}
// -----------------------------------------------------------------------------

<commit_msg>INTEGRATION: CWS ooo19126 (1.14.250); FILE MERGED 2005/09/05 17:25:54 rt 1.14.250.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: VColumn.cxx,v $
 *
 *  $Revision: 1.15 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 07:42:53 $
 *
 *  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 _CONNECTIVITY_SDBCX_COLUMN_HXX_
#include "connectivity/sdbcx/VColumn.hxx"
#endif
#ifndef _COM_SUN_STAR_LANG_DISPOSEDEXCEPTION_HPP_
#include <com/sun/star/lang/DisposedException.hpp>
#endif
#ifndef _COMPHELPER_SEQUENCE_HXX_
#include <comphelper/sequence.hxx>
#endif
#ifndef CONNECTIVITY_CONNECTION_HXX
#include "TConnection.hxx"
#endif
#ifndef _COM_SUN_STAR_SDBC_COLUMNVALUE_HPP_
#include <com/sun/star/sdbc/ColumnValue.hpp>
#endif
// -------------------------------------------------------------------------
using namespace connectivity;
using namespace connectivity::sdbcx;
using namespace cppu;
using namespace connectivity;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::sdbc;

// -----------------------------------------------------------------------------
::rtl::OUString SAL_CALL OColumn::getImplementationName(  ) throw (::com::sun::star::uno::RuntimeException)
{
    if(isNew())
        return ::rtl::OUString::createFromAscii("com.sun.star.sdbcx.VColumnDescription");
    return ::rtl::OUString::createFromAscii("com.sun.star.sdbcx.VColumn");
}
// -----------------------------------------------------------------------------
::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL OColumn::getSupportedServiceNames(  ) throw(::com::sun::star::uno::RuntimeException)
{
    ::com::sun::star::uno::Sequence< ::rtl::OUString > aSupported(1);
    if(isNew())
        aSupported[0] = ::rtl::OUString::createFromAscii("com.sun.star.sdbcx.ColumnDescription");
    else
        aSupported[0] = ::rtl::OUString::createFromAscii("com.sun.star.sdbcx.Column");

    return aSupported;
}
// -----------------------------------------------------------------------------
sal_Bool SAL_CALL OColumn::supportsService( const ::rtl::OUString& _rServiceName ) throw(::com::sun::star::uno::RuntimeException)
{
    Sequence< ::rtl::OUString > aSupported(getSupportedServiceNames());
    const ::rtl::OUString* pSupported = aSupported.getConstArray();
    const ::rtl::OUString* pEnd = pSupported + aSupported.getLength();
    for (;pSupported != pEnd && !pSupported->equals(_rServiceName); ++pSupported)
        ;

    return pSupported != pEnd;
}
// -------------------------------------------------------------------------
OColumn::OColumn(sal_Bool _bCase)  :    OColumnDescriptor_BASE(m_aMutex)
                    ,   ODescriptor(OColumnDescriptor_BASE::rBHelper,_bCase,sal_True)
                    ,   m_Precision(0)
                    ,   m_Type(0)
                    ,   m_Scale(0)
                    ,   m_IsNullable(ColumnValue::NULLABLE)
                    ,   m_IsAutoIncrement(sal_False)
                    ,   m_IsRowVersion(sal_False)
                    ,   m_IsCurrency(sal_False)
{
    construct();
}
// -------------------------------------------------------------------------
OColumn::OColumn(   const ::rtl::OUString& _Name,
                    const ::rtl::OUString& _TypeName,
                    const ::rtl::OUString& _DefaultValue,
                    sal_Int32       _IsNullable,
                    sal_Int32       _Precision,
                    sal_Int32       _Scale,
                    sal_Int32       _Type,
                    sal_Bool        _IsAutoIncrement,
                    sal_Bool        _IsRowVersion,
                    sal_Bool        _IsCurrency,
                    sal_Bool        _bCase)
            :   OColumnDescriptor_BASE(m_aMutex)
            ,   ODescriptor(OColumnDescriptor_BASE::rBHelper,_bCase)
            ,   m_TypeName(_TypeName)
            ,   m_DefaultValue(_DefaultValue)
            ,   m_Precision(_Precision)
            ,   m_Type(_Type)
            ,   m_Scale(_Scale)
            ,   m_IsNullable(_IsNullable)
            ,   m_IsAutoIncrement(_IsAutoIncrement)
            ,   m_IsRowVersion(_IsRowVersion)
            ,   m_IsCurrency(_IsCurrency)
{
    m_Name = _Name;

    construct();
}
// -------------------------------------------------------------------------
OColumn::~OColumn()
{
}
// -----------------------------------------------------------------------------
::cppu::IPropertyArrayHelper* OColumn::createArrayHelper( sal_Int32 _nId) const
{
    ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property > aProps;
    describeProperties(aProps);
    changePropertyAttributte(aProps);
    return new ::cppu::OPropertyArrayHelper(aProps);
}
// -----------------------------------------------------------------------------
::cppu::IPropertyArrayHelper& SAL_CALL OColumn::getInfoHelper()
{
    return *OColumn_PROP::getArrayHelper(isNew() ? 1 : 0);
}
// -----------------------------------------------------------------------------
void SAL_CALL OColumn::acquire() throw()
{
    OColumnDescriptor_BASE::acquire();
}
// -----------------------------------------------------------------------------
void SAL_CALL OColumn::release() throw()
{
    OColumnDescriptor_BASE::release();
}
// -----------------------------------------------------------------------------
Any SAL_CALL OColumn::queryInterface( const Type & rType ) throw(RuntimeException)
{
    Any aRet = ODescriptor::queryInterface( rType);
    if(!aRet.hasValue())
    {
        if(!isNew())
            aRet = OColumn_BASE::queryInterface(rType);
        if(!aRet.hasValue())
            aRet = OColumnDescriptor_BASE::queryInterface( rType);
    }
    return aRet;
}
// -------------------------------------------------------------------------
Sequence< Type > SAL_CALL OColumn::getTypes(  ) throw(RuntimeException)
{
    if(isNew())
        return ::comphelper::concatSequences(ODescriptor::getTypes(),OColumnDescriptor_BASE::getTypes());

    return ::comphelper::concatSequences(ODescriptor::getTypes(),OColumn_BASE::getTypes(),OColumnDescriptor_BASE::getTypes());
}
// -------------------------------------------------------------------------
void OColumn::construct()
{
    ODescriptor::construct();

    sal_Int32 nAttrib = isNew() ? 0 : PropertyAttribute::READONLY;

    registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPENAME),            PROPERTY_ID_TYPENAME,           nAttrib,&m_TypeName,        ::getCppuType(reinterpret_cast< ::rtl::OUString*>(NULL)));
    registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_DESCRIPTION),     PROPERTY_ID_DESCRIPTION,        nAttrib,&m_Description,     ::getCppuType(reinterpret_cast< ::rtl::OUString*>(NULL)));
    registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_DEFAULTVALUE),        PROPERTY_ID_DEFAULTVALUE,       nAttrib,&m_DefaultValue,    ::getCppuType(reinterpret_cast< ::rtl::OUString*>(NULL)));
    registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_PRECISION),       PROPERTY_ID_PRECISION,          nAttrib,&m_Precision,       ::getCppuType(reinterpret_cast<sal_Int32*>(NULL)));
    registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE),                PROPERTY_ID_TYPE,               nAttrib,&m_Type,            ::getCppuType(reinterpret_cast<sal_Int32*>(NULL)));
    registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_SCALE),           PROPERTY_ID_SCALE,              nAttrib,&m_Scale,           ::getCppuType(reinterpret_cast<sal_Int32*>(NULL)));
    registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ISNULLABLE),      PROPERTY_ID_ISNULLABLE,         nAttrib,&m_IsNullable,      ::getCppuType(reinterpret_cast<sal_Int32*>(NULL)));
    registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ISAUTOINCREMENT), PROPERTY_ID_ISAUTOINCREMENT,    nAttrib,&m_IsAutoIncrement, ::getBooleanCppuType());
    registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ISROWVERSION),        PROPERTY_ID_ISROWVERSION,       nAttrib,&m_IsRowVersion,    ::getBooleanCppuType());
    registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ISCURRENCY),      PROPERTY_ID_ISCURRENCY,         nAttrib,&m_IsCurrency,      ::getBooleanCppuType());
}
// -------------------------------------------------------------------------
void OColumn::disposing(void)
{
    OPropertySetHelper::disposing();

    ::osl::MutexGuard aGuard(m_aMutex);
    checkDisposed(OColumnDescriptor_BASE::rBHelper.bDisposed);

}
// -------------------------------------------------------------------------
Reference< XPropertySet > SAL_CALL OColumn::createDataDescriptor(  ) throw(RuntimeException)
{
    ::osl::MutexGuard aGuard(m_aMutex);
    checkDisposed(OColumnDescriptor_BASE::rBHelper.bDisposed);

    OColumn* pNewColumn = new OColumn(  m_Name,
                                        m_TypeName,
                                        m_DefaultValue,
                                        m_IsNullable,
                                        m_Precision,
                                        m_Scale,
                                        m_Type,
                                        m_IsAutoIncrement,
                                        m_IsRowVersion,
                                        m_IsCurrency,
                                        isCaseSensitive());
    pNewColumn->m_Description = m_Description;
    pNewColumn->setNew(sal_True);
    return pNewColumn;
}
// -----------------------------------------------------------------------------
::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL OColumn::getPropertySetInfo(  ) throw(::com::sun::star::uno::RuntimeException)
{
    return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper());
}
// -----------------------------------------------------------------------------
// XNamed
::rtl::OUString SAL_CALL OColumn::getName(  ) throw(::com::sun::star::uno::RuntimeException)
{
    return m_Name;
}
// -----------------------------------------------------------------------------
void SAL_CALL OColumn::setName( const ::rtl::OUString& aName ) throw(::com::sun::star::uno::RuntimeException)
{
    m_Name = aName;
}
// -----------------------------------------------------------------------------

<|endoftext|>


<commit_before>#ifndef AIKIDO_UTIL_RNG_H_
#define AIKIDO_UTIL_RNG_H_

#include <ctime>
#include <memory>
#include <stdint.h>

namespace aikido {
namespace util {

class RNG
{
public:
  typedef uint32_t result_type;

  virtual result_type min() const = 0;
  virtual result_type max() const = 0;
  virtual result_type operator()() = 0;
  virtual std::unique_ptr<RNG> clone() const = 0;

};

template <class T>
class RNGWrapper : virtual public RNG
{
public:

  RNGWrapper()
    : mRng(std::time(0))
  {
  }

  RNGWrapper(T _rng)
    : mRng(_rng)
  {
  }

  RNGWrapper(result_type _seed)
    : mRng(_seed)
  {
  }

  T &rng()
  {
    return mRng;
  }

  T const &rng() const
  {
    return mRng;
  }

  virtual result_type min() const
  {
    return mRng.min();
  }

  virtual result_type max() const
  {
    return mRng.max();
  }

  virtual result_type operator()()
  {
    return mRng();
  }

  virtual std::unique_ptr<RNG> clone() const override
  {
    return std::unique_ptr<RNG>(new RNGWrapper(mRng));
  }

private:
  T mRng;
};

} // util
} // aikido

#endif // AIKIDO_UTIL_RNG_H_
<commit_msg>Added missing 'override's.<commit_after>#ifndef AIKIDO_UTIL_RNG_H_
#define AIKIDO_UTIL_RNG_H_

#include <ctime>
#include <memory>
#include <stdint.h>

namespace aikido {
namespace util {

class RNG
{
public:
  typedef uint32_t result_type;

  virtual result_type min() const = 0;
  virtual result_type max() const = 0;
  virtual result_type operator()() = 0;
  virtual std::unique_ptr<RNG> clone() const = 0;

};

template <class T>
class RNGWrapper : virtual public RNG
{
public:

  RNGWrapper()
    : mRng(std::time(0))
  {
  }

  RNGWrapper(T _rng)
    : mRng(_rng)
  {
  }

  RNGWrapper(result_type _seed)
    : mRng(_seed)
  {
  }

  T &rng()
  {
    return mRng;
  }

  T const &rng() const
  {
    return mRng;
  }

  result_type min() const override
  {
    return mRng.min();
  }

  result_type max() const override
  {
    return mRng.max();
  }

  result_type operator()() override
  {
    return mRng();
  }

  std::unique_ptr<RNG> clone() const override
  {
    return std::unique_ptr<RNGWrapper>(new RNGWrapper(mRng));
  }

private:
  T mRng;
};

} // util
} // aikido

#endif // AIKIDO_UTIL_RNG_H_
<|endoftext|>


<commit_before>/**
 * \file dcs/testbed/application_experiment.hpp
 *
 * \brief Represents an experiment for a single application.
 *
 * \author Marco Guazzone (marco.guazzone@gmail.com)
 *
 *

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

#ifndef DCS_TESTBED_APPLICATION_EXPERIMENT_HPP
#define DCS_TESTBED_APPLICATION_EXPERIMENT_HPP

#include <boost/chrono.hpp>
#include <boost/signals2/signal.hpp>
#include <boost/smart_ptr.hpp>
#include <boost/thread.hpp>
#include <dcs/assert.hpp>
#include <dcs/debug.hpp>
#include <dcs/exception.hpp>
#include <dcs/testbed/base_application.hpp>
#include <dcs/testbed/base_application_manager.hpp>
#include <dcs/testbed/base_workload_driver.hpp>
#include <dcs/testbed/detail/runnable.hpp>
#include <map>
#include <stdexcept>
#include <vector>

namespace dcs { namespace testbed {

namespace detail { namespace /*<unnamed>*/ {

template <typename T, typename MT>
struct sampler_runnable
{
	sampler_runnable(::boost::weak_ptr<T> const& ptr, MT& mutex)
	: wp_(ptr),
	  mtx_(mutex)
	{
	}

	void operator()()
	{
		DCS_DEBUG_TRACE("SAMPLER THREAD: Entering...");

		::boost::shared_ptr<T> sp(wp_.lock());

		// Transform secs into millisecs so that the conversion real->uint keeps some decimal
		typename T::traits_type::uint_type ts = 1000.0*sp->sampling_time();

		// Loop forever until we get interrupted
		while (true)
		{
			{
				::boost::lock_guard< ::boost::mutex > lock(mtx_);

				sp->sample();
			}

			::boost::this_thread::sleep_for(::boost::chrono::milliseconds(ts));
		}

		DCS_DEBUG_TRACE("SAMPLER THREAD: Leaving...");
	}

	::boost::weak_ptr<T> wp_;
	MT& mtx_;
}; // sampler_runnable

template <typename T, typename MT>
struct controller_runnable
{
	controller_runnable(::boost::weak_ptr<T> const& ptr, MT& mutex)
	: wp_(ptr),
	  mtx_(mutex)
	{
	}

	void operator()()
	{
		DCS_DEBUG_TRACE("CONTROLLER THREAD: Entering...");

		::boost::shared_ptr<T> sp(wp_.lock());

		// Transform secs into millisecs so that the conversion real-> uint keeps some decimal
		typename T::traits_type::uint_type ts = 1000.0*sp->control_time();

		// Loop forever until we get interrupted
		while (true)
		{
			{
				::boost::lock_guard< ::boost::mutex > lock(mtx_);

				sp->control();
			}

			::boost::this_thread::sleep_for(::boost::chrono::milliseconds(ts));
		}

		DCS_DEBUG_TRACE("CONTROLLER THREAD: Leaving...");
	}

	::boost::weak_ptr<T> wp_;
	MT& mtx_;
}; // controller_runnable

/*
template <typename T, typename MT>
struct monitor_runnable
{
	monitor_runnable(::boost::weak_ptr<T> const& ptr, MT& mutex)
	: wp_(ptr),
	  mtx_(mutex)
	{
	}

	void operator()()
	{
		DCS_DEBUG_TRACE("MONITOR THREAD: Entering...");

		::boost::shared_ptr<T> sp(wp_.lock());

		// Transform secs into millisecs so that the conversion real -> uint keeps some decimal
		typename T::traits_type::uint_type ts = 1000.0*sp->monitoring_time();

		// Loop forever until we get interrupted
		while (true)
		{
			{
				::boost::lock_guard< ::boost::mutex > lock(mtx_);

				sp->monitor();
			}

			::boost::this_thread::sleep_for(::boost::chrono::milliseconds(ts));
		}

		DCS_DEBUG_TRACE("MONITOR THREAD: Leaving...");
	}

	::boost::weak_ptr<T> wp_;
	MT& mtx_;
}; // monitor_runnable
*/
 }} // Namespace detail::<unnamed>

template <typename TraitsT>
class application_experiment
{
	private: typedef application_experiment<TraitsT> self_type;
	public: typedef TraitsT traits_type;
	public: typedef typename traits_type::real_type real_type;
	public: typedef unsigned long identifier_type;
	private: typedef base_application<traits_type> app_type;
	public: typedef ::boost::shared_ptr<app_type> app_pointer;
	private: typedef base_workload_driver<traits_type> driver_type;
	public: typedef ::boost::shared_ptr<driver_type> driver_pointer;
	private: typedef base_application_manager<traits_type> manager_type;
	public: typedef ::boost::shared_ptr<manager_type> manager_pointer;
	private: typedef ::boost::signals2::signal<void (self_type const&)> signal_type;
	private: typedef ::boost::shared_ptr<signal_type> signal_pointer;

	//private: static ::boost::mutex mtx_;
	private: static identifier_type next_id_;

	private: static identifier_type make_id()
	{
		//::boost::lock_guard< ::boost::mutex > lock(mtx_);

		return next_id_++;
	}

	public: application_experiment(app_pointer const& p_app,
								   driver_pointer const& p_drv,
								   manager_pointer const& p_mgr)
	: id_(make_id()),
	  p_app_(p_app),
	  p_drv_(p_drv),
	  p_mgr_(p_mgr),
	  restore_state_(true),
	  p_sta_sig_(new signal_type()),
	  p_sto_sig_(new signal_type())
	{
	}

	public: ~application_experiment()
	{
		try
		{
			restore_app_state();
		}
		catch (...)
		{
		}
	}

	public: identifier_type id() const
	{
		return id_;
	}

	public: void app(app_pointer const& p_app)
	{
		p_app_ = p_app;
	}

	public: app_type& app()
	{
		return *p_app_;
	}

	public: app_type const& app() const
	{
		return *p_app_;
	}

	public: void driver(driver_pointer const& p_drv)
	{
		p_drv_ = p_drv;
	}

	public: driver_type& driver()
	{
		return *p_drv_;
	}

	public: driver_type const& driver() const
	{
		return *p_drv_;
	}

	public: void manager(manager_pointer const& p_mgr)
	{
		p_mgr_ = p_mgr;
	}

	public: manager_type& manager()
	{
		return *p_mgr_;
	}

	public: manager_type const& manager() const
	{
		return *p_mgr_;
	}

	public: void restore_state(bool value)
	{
		restore_state_ = value;
	}

	public: bool restore_state() const
	{
		return restore_state_;
	}

	public: template <typename FuncT>
			void add_on_start_handler(FuncT f)
	{
		p_sta_sig_->connect(f);
	}

	public: template <typename FuncT>
			void add_on_stop_handler(FuncT f)
	{
		p_sto_sig_->connect(f);
	}

	public: void run()
	{
		DCS_ASSERT(p_app_,
				   DCS_EXCEPTION_THROW(::std::runtime_error,
									   "Application not set"));
		DCS_ASSERT(p_drv_,
				   DCS_EXCEPTION_THROW(::std::runtime_error,
									   "Driver not set"));
		DCS_ASSERT(p_mgr_,
				   DCS_EXCEPTION_THROW(::std::runtime_error,
									   "Manager not set"));

//		typedef typename monitor_container::iterator monitor_iterator;

		const unsigned long zzz_time = 5;

		running_ = true;

		save_app_state();

		p_mgr_->app(p_app_);
		p_mgr_->reset();
		p_drv_->app(p_app_);
		p_drv_->reset();
//		monitor_iterator mon_beg_it(mons_.begin());
//		monitor_iterator mon_end_it(mons_.end());
//		for (monitor_iterator mon_it = mon_beg_it;
//			 mon_it != mon_end_it;
//			 ++mon_it)
//		{
//			mon_it->app(p_app_);
//			mon_it->reset();
//		}

		(*p_sta_sig_)(*this);

		p_drv_->start();

		::boost::thread_group mgr_thd_grp;
		::boost::mutex mgr_mtx;
		bool mgr_run = false;
		while (!p_drv_->done())
		{
			if (!mgr_run && p_drv_->ready())
			{
				detail::sampler_runnable<manager_type,::boost::mutex> mgr_smp_runner(p_mgr_, mgr_mtx);
				mgr_thd_grp.create_thread(mgr_smp_runner);

				detail::controller_runnable<manager_type,::boost::mutex> mgr_ctl_runner(p_mgr_, mgr_mtx);
				mgr_thd_grp.create_thread(mgr_ctl_runner);

//				for (monitor_iterator mon_it = mon_beg_it;
//					 mon_it != mon_end_it;
//					 ++mon_it)
//				{
//					detail::monitor_runnable<monitor_type,::boost::mutex> mgr_mon_runner(*mon_it, mgr_mtx);
//					mgr_thd_grp.create_thread(mgr_mon_runner);
//				}

				mgr_run = true;
			}

			::boost::this_thread::sleep_for(::boost::chrono::seconds(zzz_time));
		}

		mgr_thd_grp.interrupt_all();
		mgr_thd_grp.join_all();

		p_drv_->stop();

		restore_app_state();

		(*p_sto_sig_)(*this);

		running_ = false;
	}

	protected: app_pointer app_ptr()
	{
		return p_app_;
	}

	protected: app_pointer const& app_ptr() const
	{
		return p_app_;
	}

	protected: driver_pointer driver_ptr()
	{
		return p_drv_;
	}

	protected: driver_pointer const& driver_ptr() const
	{
		return p_drv_;
	}

	protected: manager_pointer manager_ptr()
	{
		return p_mgr_;
	}

	protected: manager_pointer const& manager_ptr() const
	{
		return p_mgr_;
	}

	private: void save_app_state()
	{
		if (!restore_state_ || !p_app_ || !running_)
		{
			return;
		}

		typedef typename app_type::vm_pointer vm_pointer;
		typedef ::std::vector<vm_pointer> vm_container;
		typedef typename vm_container::const_iterator vm_iterator;
		vm_container vms = this->app().vms();
		vm_iterator vm_end_it = vms.end();
		for (vm_iterator vm_it = vms.begin();
			 vm_it != vm_end_it;
			 ++vm_it)
		{
			vm_pointer p_vm(*vm_it);

			// check: p_vm != null
			DCS_DEBUG_ASSERT( p_vm );

			vm_states_[p_vm->id()] = p_vm->cpu_share();
		}
	}

	private: void restore_app_state()
	{
		if (!restore_state_ || !p_app_ || !running_)
		{
			return;
		}

		typedef typename app_type::vm_pointer vm_pointer;
		typedef ::std::vector<vm_pointer> vm_container;
		typedef typename vm_container::const_iterator vm_iterator;
		vm_container vms = this->app().vms();
		vm_iterator vm_end_it = vms.end();
		for (vm_iterator vm_it = vms.begin();
			 vm_it != vm_end_it;
			 ++vm_it)
		{
			vm_pointer p_vm(*vm_it);

			// check: p_vm != null
			DCS_DEBUG_ASSERT( p_vm );

			p_vm->cpu_share(vm_states_.at(p_vm->id()));
		}
	}

	private: const identifier_type id_; ///< The unique experiment identifier
	private: app_pointer p_app_; ///< Pointer to the application
	private: driver_pointer p_drv_; ///< Pointer to the application driver
	private: manager_pointer p_mgr_; ///< Pointer to the application manager
	private: bool restore_state_; ///< Tell if the state of the application should or should not be restored after experiment's completion
	private: signal_pointer p_sta_sig_;
	private: signal_pointer p_sto_sig_;
	private: ::std::map<typename app_type::vm_type::identifier_type,real_type> vm_states_;
	private: bool running_;
}; // application_experiment

template <typename T>
typename application_experiment<T>::identifier_type application_experiment<T>::next_id_ = 0;

}} // Namespace dcs::testbed

#endif // DCS_TESTBED_APPLICATION_EXPERIMENT_HPP
<commit_msg>(new) Added 'name' member to VMM<commit_after>/**
 * \file dcs/testbed/application_experiment.hpp
 *
 * \brief Represents an experiment for a single application.
 *
 * \author Marco Guazzone (marco.guazzone@gmail.com)
 *
 *

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

#ifndef DCS_TESTBED_APPLICATION_EXPERIMENT_HPP
#define DCS_TESTBED_APPLICATION_EXPERIMENT_HPP

#include <boost/chrono.hpp>
#include <boost/signals2/signal.hpp>
#include <boost/smart_ptr.hpp>
#include <boost/thread.hpp>
#include <dcs/assert.hpp>
#include <dcs/debug.hpp>
#include <dcs/exception.hpp>
#include <dcs/testbed/base_application.hpp>
#include <dcs/testbed/base_application_manager.hpp>
#include <dcs/testbed/base_workload_driver.hpp>
#include <dcs/testbed/detail/runnable.hpp>
#include <map>
#include <sstream>
#include <stdexcept>
#include <vector>

namespace dcs { namespace testbed {

namespace detail { namespace /*<unnamed>*/ {

template <typename T, typename MT>
struct sampler_runnable
{
	sampler_runnable(::boost::weak_ptr<T> const& ptr, MT& mutex)
	: wp_(ptr),
	  mtx_(mutex)
	{
	}

	void operator()()
	{
		DCS_DEBUG_TRACE("SAMPLER THREAD: Entering...");

		::boost::shared_ptr<T> sp(wp_.lock());

		// Transform secs into millisecs so that the conversion real->uint keeps some decimal
		typename T::traits_type::uint_type ts = 1000.0*sp->sampling_time();

		// Loop forever until we get interrupted
		while (true)
		{
			{
				::boost::lock_guard< ::boost::mutex > lock(mtx_);

				sp->sample();
			}

			::boost::this_thread::sleep_for(::boost::chrono::milliseconds(ts));
		}

		DCS_DEBUG_TRACE("SAMPLER THREAD: Leaving...");
	}

	::boost::weak_ptr<T> wp_;
	MT& mtx_;
}; // sampler_runnable

template <typename T, typename MT>
struct controller_runnable
{
	controller_runnable(::boost::weak_ptr<T> const& ptr, MT& mutex)
	: wp_(ptr),
	  mtx_(mutex)
	{
	}

	void operator()()
	{
		DCS_DEBUG_TRACE("CONTROLLER THREAD: Entering...");

		::boost::shared_ptr<T> sp(wp_.lock());

		// Transform secs into millisecs so that the conversion real-> uint keeps some decimal
		typename T::traits_type::uint_type ts = 1000.0*sp->control_time();

		// Loop forever until we get interrupted
		while (true)
		{
			{
				::boost::lock_guard< ::boost::mutex > lock(mtx_);

				sp->control();
			}

			::boost::this_thread::sleep_for(::boost::chrono::milliseconds(ts));
		}

		DCS_DEBUG_TRACE("CONTROLLER THREAD: Leaving...");
	}

	::boost::weak_ptr<T> wp_;
	MT& mtx_;
}; // controller_runnable

/*
template <typename T, typename MT>
struct monitor_runnable
{
	monitor_runnable(::boost::weak_ptr<T> const& ptr, MT& mutex)
	: wp_(ptr),
	  mtx_(mutex)
	{
	}

	void operator()()
	{
		DCS_DEBUG_TRACE("MONITOR THREAD: Entering...");

		::boost::shared_ptr<T> sp(wp_.lock());

		// Transform secs into millisecs so that the conversion real -> uint keeps some decimal
		typename T::traits_type::uint_type ts = 1000.0*sp->monitoring_time();

		// Loop forever until we get interrupted
		while (true)
		{
			{
				::boost::lock_guard< ::boost::mutex > lock(mtx_);

				sp->monitor();
			}

			::boost::this_thread::sleep_for(::boost::chrono::milliseconds(ts));
		}

		DCS_DEBUG_TRACE("MONITOR THREAD: Leaving...");
	}

	::boost::weak_ptr<T> wp_;
	MT& mtx_;
}; // monitor_runnable
*/
 }} // Namespace detail::<unnamed>

template <typename TraitsT>
class application_experiment
{
	private: typedef application_experiment<TraitsT> self_type;
	public: typedef TraitsT traits_type;
	public: typedef typename traits_type::real_type real_type;
	public: typedef unsigned long identifier_type;
	private: typedef base_application<traits_type> app_type;
	public: typedef ::boost::shared_ptr<app_type> app_pointer;
	private: typedef base_workload_driver<traits_type> driver_type;
	public: typedef ::boost::shared_ptr<driver_type> driver_pointer;
	private: typedef base_application_manager<traits_type> manager_type;
	public: typedef ::boost::shared_ptr<manager_type> manager_pointer;
	private: typedef ::boost::signals2::signal<void (self_type const&)> signal_type;
	private: typedef ::boost::shared_ptr<signal_type> signal_pointer;

	//private: static ::boost::mutex mtx_;
	private: static identifier_type next_id_;

	private: static identifier_type make_id()
	{
		//::boost::lock_guard< ::boost::mutex > lock(mtx_);

		return next_id_++;
	}

	private: static std::string make_name(identifier_type id)
	{
		std::ostringstream oss;
		oss << "Experiment " << id;
		return oss.str();
	}

	public: application_experiment()
	: id_(make_id()),
	  name_(make_name(id_)),
	  restore_state_(true),
	  p_sta_sig_(new signal_type()),
	  p_sto_sig_(new signal_type())
	{
	}

	public: application_experiment(app_pointer const& p_app,
								   driver_pointer const& p_drv,
								   manager_pointer const& p_mgr)
	: id_(make_id()),
	  name_(make_name(id_)),
	  p_app_(p_app),
	  p_drv_(p_drv),
	  p_mgr_(p_mgr),
	  restore_state_(true),
	  p_sta_sig_(new signal_type()),
	  p_sto_sig_(new signal_type())
	{
	}

	public: ~application_experiment()
	{
		try
		{
			restore_app_state();
		}
		catch (...)
		{
		}
	}

	public: identifier_type id() const
	{
		return id_;
	}

	public: std::string name() const
	{
		return name_;
	}

	public: void name(std::string const& s)
	{
		name_ = s;
	}

	public: void app(app_pointer const& p_app)
	{
		p_app_ = p_app;
	}

	public: app_type& app()
	{
		return *p_app_;
	}

	public: app_type const& app() const
	{
		return *p_app_;
	}

	public: void driver(driver_pointer const& p_drv)
	{
		p_drv_ = p_drv;
	}

	public: driver_type& driver()
	{
		return *p_drv_;
	}

	public: driver_type const& driver() const
	{
		return *p_drv_;
	}

	public: void manager(manager_pointer const& p_mgr)
	{
		p_mgr_ = p_mgr;
	}

	public: manager_type& manager()
	{
		return *p_mgr_;
	}

	public: manager_type const& manager() const
	{
		return *p_mgr_;
	}

	public: void restore_state(bool value)
	{
		restore_state_ = value;
	}

	public: bool restore_state() const
	{
		return restore_state_;
	}

	public: template <typename FuncT>
			void add_on_start_handler(FuncT f)
	{
		p_sta_sig_->connect(f);
	}

	public: template <typename FuncT>
			void add_on_stop_handler(FuncT f)
	{
		p_sto_sig_->connect(f);
	}

	public: void run()
	{
		DCS_ASSERT(p_app_,
				   DCS_EXCEPTION_THROW(::std::runtime_error,
									   "Application not set"));
		DCS_ASSERT(p_drv_,
				   DCS_EXCEPTION_THROW(::std::runtime_error,
									   "Driver not set"));
		DCS_ASSERT(p_mgr_,
				   DCS_EXCEPTION_THROW(::std::runtime_error,
									   "Manager not set"));

//		typedef typename monitor_container::iterator monitor_iterator;

		const unsigned long zzz_time = 5;

		running_ = true;

		save_app_state();

		p_mgr_->app(p_app_);
		p_mgr_->reset();
		p_drv_->app(p_app_);
		p_drv_->reset();
//		monitor_iterator mon_beg_it(mons_.begin());
//		monitor_iterator mon_end_it(mons_.end());
//		for (monitor_iterator mon_it = mon_beg_it;
//			 mon_it != mon_end_it;
//			 ++mon_it)
//		{
//			mon_it->app(p_app_);
//			mon_it->reset();
//		}

		(*p_sta_sig_)(*this);

		p_drv_->start();

		::boost::thread_group mgr_thd_grp;
		::boost::mutex mgr_mtx;
		bool mgr_run = false;
		while (!p_drv_->done())
		{
			if (!mgr_run && p_drv_->ready())
			{
				detail::sampler_runnable<manager_type,::boost::mutex> mgr_smp_runner(p_mgr_, mgr_mtx);
				mgr_thd_grp.create_thread(mgr_smp_runner);

				detail::controller_runnable<manager_type,::boost::mutex> mgr_ctl_runner(p_mgr_, mgr_mtx);
				mgr_thd_grp.create_thread(mgr_ctl_runner);

//				for (monitor_iterator mon_it = mon_beg_it;
//					 mon_it != mon_end_it;
//					 ++mon_it)
//				{
//					detail::monitor_runnable<monitor_type,::boost::mutex> mgr_mon_runner(*mon_it, mgr_mtx);
//					mgr_thd_grp.create_thread(mgr_mon_runner);
//				}

				mgr_run = true;
			}

			::boost::this_thread::sleep_for(::boost::chrono::seconds(zzz_time));
		}

		mgr_thd_grp.interrupt_all();
		mgr_thd_grp.join_all();

		p_drv_->stop();

		restore_app_state();

		(*p_sto_sig_)(*this);

		running_ = false;
	}

	protected: app_pointer app_ptr()
	{
		return p_app_;
	}

	protected: app_pointer const& app_ptr() const
	{
		return p_app_;
	}

	protected: driver_pointer driver_ptr()
	{
		return p_drv_;
	}

	protected: driver_pointer const& driver_ptr() const
	{
		return p_drv_;
	}

	protected: manager_pointer manager_ptr()
	{
		return p_mgr_;
	}

	protected: manager_pointer const& manager_ptr() const
	{
		return p_mgr_;
	}

	private: void save_app_state()
	{
		if (!restore_state_ || !p_app_ || !running_)
		{
			return;
		}

		typedef typename app_type::vm_pointer vm_pointer;
		typedef ::std::vector<vm_pointer> vm_container;
		typedef typename vm_container::const_iterator vm_iterator;
		vm_container vms = this->app().vms();
		vm_iterator vm_end_it = vms.end();
		for (vm_iterator vm_it = vms.begin();
			 vm_it != vm_end_it;
			 ++vm_it)
		{
			vm_pointer p_vm(*vm_it);

			// check: p_vm != null
			DCS_DEBUG_ASSERT( p_vm );

			vm_states_[p_vm->id()] = p_vm->cpu_share();
		}
	}

	private: void restore_app_state()
	{
		if (!restore_state_ || !p_app_ || !running_)
		{
			return;
		}

		typedef typename app_type::vm_pointer vm_pointer;
		typedef ::std::vector<vm_pointer> vm_container;
		typedef typename vm_container::const_iterator vm_iterator;
		vm_container vms = this->app().vms();
		vm_iterator vm_end_it = vms.end();
		for (vm_iterator vm_it = vms.begin();
			 vm_it != vm_end_it;
			 ++vm_it)
		{
			vm_pointer p_vm(*vm_it);

			// check: p_vm != null
			DCS_DEBUG_ASSERT( p_vm );

			p_vm->cpu_share(vm_states_.at(p_vm->id()));
		}
	}

	private: const identifier_type id_; ///< The unique experiment identifier
	private: std::string name_; ///< A mnemonic name for the experiment
	private: app_pointer p_app_; ///< Pointer to the application
	private: driver_pointer p_drv_; ///< Pointer to the application driver
	private: manager_pointer p_mgr_; ///< Pointer to the application manager
	private: bool restore_state_; ///< Tell if the state of the application should or should not be restored after experiment's completion
	private: signal_pointer p_sta_sig_;
	private: signal_pointer p_sto_sig_;
	private: ::std::map<typename app_type::vm_type::identifier_type,real_type> vm_states_;
	private: bool running_;
}; // application_experiment

template <typename T>
typename application_experiment<T>::identifier_type application_experiment<T>::next_id_ = 0;

}} // Namespace dcs::testbed

#endif // DCS_TESTBED_APPLICATION_EXPERIMENT_HPP
<|endoftext|>


<commit_before>#pragma once

#include <cassert>
#include <iostream>
#include <string>

#include "fixfmt/math.hh"

//------------------------------------------------------------------------------

namespace fixfmt {

using std::string;

constexpr char const* ELLIPSIS = "\u2026";

/**
 * Advances an iterator on a UTF-8 string by one code point.
 */
// FIXME: Take an end parameter.
inline void
next_utf8(string::const_iterator& i)
{
  unsigned char c = *i++;
  if ((c & 0xc0) == 0xc0) {
    // It's multibyte.  The number of bytes is the number of MSB's before
    // the first zero.
    // FIXME: Improve this.
    ++i;
    if ((c & 0xe0) == 0xe0) {
      ++i;
      if ((c & 0xf0) == 0xf0) {
        ++i;
        if ((c & 0xf8) == 0xf8) {
          ++i;
          if ((c & 0xfc) == 0xfc)
            ++i;
        }
      }
    }
  }
}

/**
 * Returns the number of code points in a UTF-8-encoded string.
 */
inline size_t
utf8_length(string const& str)
{
  size_t length = 0;
  // FIXME: Problem if the last code point is malformed.
  for (auto i = str.begin(); i != str.end(); next_utf8(i))
    ++length;
  return length;
}

// FIXME: Elsewhere.

constexpr char ANSI_ESCAPE = '\x1b';

inline bool
within(unsigned char min, unsigned char val, unsigned char max)
{
  return min <= val && val <= max;
}

/**
 * Advances an iterator past an ANSI escape sequence, if it is positioned at
 * one.
 */
inline bool
skip_ansi_escape(string::const_iterator& i, string::const_iterator const& end)
{
  assert(i != end);
  if (*i == ANSI_ESCAPE) {
    ++i;
    if (i != end && *i++ == '[')
      // Got CSI.  Read until we pass a final byte.
      while (i != end && !within(64, *i++, 126))
        ;
    else
      // Assume single-character escape.
      ;
    return true;
  }
  else
    return false;
}

/**
 * Returns the number of code points in a UTF-8-encoded string, skipping
 * escape sequences.
 */
inline size_t
string_length(string const& str)
{
  size_t length = 0;
  auto const& end = str.end();
  // FIXME: Problem if the last code point is malformed.
  // Count characters.
  for (auto i = str.begin(); i != end; )
    if (skip_ansi_escape(i, end))
      ;
    else {
      ++length;
      next_utf8(i);
    }
  return length;
}

/**
 * Concatenates copies of `str` up to `length`.  If `length` is not divisible
 * by the length of `str`, the last copy is partial.
 */
inline string
fill(
  string const& str,
  size_t const length)
{
  size_t const str_len = string_length(str);
  assert(str_len > 0);
  if (str.length() == 1)
    return string(length, str[0]);
  else {
    string result;
    result.reserve(length);
    // Concatenate whole copies.
    size_t l = length;
    while (l >= str_len) {
      result += str;
      l -= str_len;
    }
    if (l > 0) {
      // Concatenate a partial copy.
      auto i = str.begin();
      for (; l > 0; --l)
        next_utf8(i);
      result.append(str.begin(), i);
    }
    assert(string_length(result) == length);
    return result;
  }
}

inline string
pad(
  string const& str,
  size_t const length,
  string const& pad=" ",
  bool const left=false)
{
  size_t const str_len = string_length(str);
  if (str_len < length) {
    string const padding = fill(pad, length - str_len);
    string const result = left ? padding + str : str + padding;
    assert(string_length(result) == length);
    return result;
  }
  else
    return str;
}

inline string
elide(
  string const& str,
  size_t const max_length,
  string const& ellipsis=ELLIPSIS,
  float const position=1.0)
{
  size_t const ellipsis_len = string_length(ellipsis);
  assert(max_length >= ellipsis_len);
  assert(0 <= position);
  assert(position <= 1);

  size_t const length = string_length(str);
  if (length <= max_length)
    return str;
  else {
    size_t const keep   = max_length - ellipsis_len;
    size_t const nleft  = (size_t) round(position * keep);
    size_t const nright = keep - nleft;
    string elided;
    if (nleft > 0)
      elided += str.substr(0, nleft);
    elided += ellipsis;
    if (nright > 0)
      elided += str.substr(length - nright);
    assert(string_length(elided) == max_length);
    return elided;
  }
}

inline string
palide(
  string const& str,
  size_t const length,
  string const& ellipsis=ELLIPSIS,
  string const& pad=" ",
  float const position=1.0,
  bool const left=false)
{
  return fixfmt::pad(elide(str, length, ellipsis, position), length, pad, left);
}

}  // namespace fixfmt
<commit_msg>Cleanups.<commit_after>#pragma once

#include <cassert>
#include <iostream>
#include <string>

#include "fixfmt/math.hh"

//------------------------------------------------------------------------------

namespace {

inline bool
within(unsigned char min, unsigned char val, unsigned char max)
{
  return min <= val && val <= max;
}

}  // anonymous namespace

//------------------------------------------------------------------------------

namespace fixfmt {

using std::string;

constexpr char const* ELLIPSIS = "\u2026";

constexpr char ANSI_ESCAPE = '\x1b';

/**
 * Advances an iterator on a UTF-8 string by one code point.
 */
// FIXME: Take an end parameter.
inline void
next_utf8(string::const_iterator& i)
{
  unsigned char c = *i++;
  if ((c & 0xc0) == 0xc0) {
    // It's multibyte.  The number of bytes is the number of MSB's before
    // the first zero.
    // FIXME: Improve this.
    ++i;
    if ((c & 0xe0) == 0xe0) {
      ++i;
      if ((c & 0xf0) == 0xf0) {
        ++i;
        if ((c & 0xf8) == 0xf8) {
          ++i;
          if ((c & 0xfc) == 0xfc)
            ++i;
        }
      }
    }
  }
}

/**
 * Returns the number of code points in a UTF-8-encoded string.
 */
inline size_t
utf8_length(string const& str)
{
  size_t length = 0;
  // FIXME: Problem if the last code point is malformed.
  for (auto i = str.begin(); i != str.end(); next_utf8(i))
    ++length;
  return length;
}

/**
 * Advances an iterator past an ANSI escape sequence, if it is positioned at
 * one.
 */
inline bool
skip_ansi_escape(string::const_iterator& i, string::const_iterator const& end)
{
  assert(i != end);
  if (*i == ANSI_ESCAPE) {
    ++i;
    if (i != end && *i++ == '[')
      // Got CSI.  Read until we pass a final byte.
      while (i != end && !within(64, *i++, 126))
        ;
    else
      // Assume single-character escape.
      ;
    return true;
  }
  else
    return false;
}

/**
 * Returns the number of code points in a UTF-8-encoded string, skipping
 * escape sequences.
 */
inline size_t
string_length(string const& str)
{
  size_t length = 0;
  auto const& end = str.end();
  // FIXME: Problem if the last code point is malformed.
  // Count characters.
  for (auto i = str.begin(); i != end; )
    if (skip_ansi_escape(i, end))
      ;
    else {
      ++length;
      next_utf8(i);
    }
  return length;
}

/**
 * Concatenates copies of `str` up to `length`.  If `length` is not divisible
 * by the length of `str`, the last copy is partial.
 */
inline string
fill(
  string const& str,
  size_t const length)
{
  size_t const str_len = string_length(str);
  assert(str_len > 0);
  if (str.length() == 1)
    return string(length, str[0]);
  else {
    string result;
    result.reserve(length);
    // Concatenate whole copies.
    size_t l = length;
    while (l >= str_len) {
      result += str;
      l -= str_len;
    }
    if (l > 0) {
      // Concatenate a partial copy.
      auto i = str.begin();
      for (; l > 0; --l)
        next_utf8(i);
      result.append(str.begin(), i);
    }
    assert(string_length(result) == length);
    return result;
  }
}

inline string
pad(
  string const& str,
  size_t const length,
  string const& pad=" ",
  bool const left=false)
{
  size_t const str_len = string_length(str);
  if (str_len < length) {
    string const padding = fill(pad, length - str_len);
    string const result = left ? padding + str : str + padding;
    assert(string_length(result) == length);
    return result;
  }
  else
    return str;
}

inline string
elide(
  string const& str,
  size_t const max_length,
  string const& ellipsis=ELLIPSIS,
  float const position=1.0)
{
  size_t const ellipsis_len = string_length(ellipsis);
  assert(max_length >= ellipsis_len);
  assert(0 <= position);
  assert(position <= 1);

  size_t const length = string_length(str);
  if (length <= max_length)
    return str;
  else {
    size_t const keep   = max_length - ellipsis_len;
    size_t const nleft  = (size_t) round(position * keep);
    size_t const nright = keep - nleft;
    string elided;
    if (nleft > 0)
      elided += str.substr(0, nleft);
    elided += ellipsis;
    if (nright > 0)
      elided += str.substr(length - nright);
    assert(string_length(elided) == max_length);
    return elided;
  }
}

inline string
palide(
  string const& str,
  size_t const length,
  string const& ellipsis=ELLIPSIS,
  string const& pad=" ",
  float const position=1.0,
  bool const left=false)
{
  return fixfmt::pad(elide(str, length, ellipsis, position), length, pad, left);
}

}  // namespace fixfmt
<|endoftext|>