<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.                  *
 **************************************************************************/

/* $Id$ */

///////////////////////////////////////////////////////////////////////////
//                                                                       //
//                          V-Zero   Detector                            //
//  This class contains the base procedures for the VZERO  detector      //
//  Default geometry of November 2003 :   V0R box is 4.4 cm thick        //
//                                  scintillators are 2 cm thick         //
//  All comments should be sent to Brigitte CHEYNIS :                    //
//                                 b.cheynis@ipnl.in2p3.fr               //
//                                                                       //
//                                                                       //
///////////////////////////////////////////////////////////////////////////

// --- Standard libraries ---
#include <Riostream.h>
#include <stdlib.h>

// --- ROOT libraries ---
#include <TNamed.h>
#include "TROOT.h"
#include "TFile.h"
#include "TNetFile.h"
#include "TRandom.h"
#include "TTree.h"
#include "TBranch.h"
#include "TClonesArray.h"
#include "TStopwatch.h"

// --- AliRoot header files ---
#include "AliRun.h"
#include "AliMC.h"
#include "AliVZERO.h"
#include "AliVZEROLoader.h"
#include "AliVZERODigitizer.h"
#include "AliVZEROBuffer.h"
#include "AliRunDigitizer.h"
#include "AliVZEROdigit.h"
#include "AliDAQ.h"
#include "AliRawReader.h"
#include "AliVZERORawStream.h"

ClassImp(AliVZERO)
 //__________________________________________________________________
AliVZERO::AliVZERO(): AliDetector(),
          fIdSens1(0),
          fThickness(0.),
	  fThickness1(0.),
	  fMaxStepQua(0.),
	  fMaxStepAlu(0.),
	  fMaxDestepQua(0.),
	  fMaxDestepAlu(0.)
{
/// Default Constructor

    AliDebug(1,Form("default (empty) ctor this=%p",this));
    fIshunt          = 0;
}
//_____________________________________________________________________________
AliVZERO::AliVZERO(const char *name, const char *title)
       : AliDetector(name,title),
         fIdSens1(0),
         fThickness(4.4),
	 fThickness1(2.0),
	 fMaxStepQua(0.05),
	 fMaxStepAlu(0.01),
	 fMaxDestepQua(-1.0),
	 fMaxDestepAlu(-1.0)
{

  // Standard constructor for VZERO Detector

  AliDebug(1,Form("ctor this=%p",this));

  //  fIshunt       =  1;  // All hits are associated with primary particles

  fHits         =  new TClonesArray("AliVZEROhit", 400);
  fDigits       =  new TClonesArray("AliVZEROdigit",400);

  gAlice->GetMCApp()->AddHitList(fHits);

//   fThickness    =  4.4;   // total thickness of the V0R box in cm
//   fThickness1   =  2.0;   // thickness of scintillating cells in cm
//
//   fMaxStepQua   =  0.05;
//   fMaxStepAlu   =  0.01;
//
//   fMaxDestepQua =  -1.0;
//   fMaxDestepAlu =  -1.0;

}

//_____________________________________________________________________________
AliVZERO::~AliVZERO()
{
  //
  // Default destructor for VZERO Detector
  //

    if (fHits) {
        fHits->Delete();
        delete fHits;
	fHits=0; }

    if (fDigits) {
        fDigits->Delete();
        delete fDigits;
        fDigits=0; }
}

//_____________________________________________________________________________
void AliVZERO::BuildGeometry()
{
  //
  // Builds simple ROOT TNode geometry for event display
  //
}

//_____________________________________________________________________________
void AliVZERO::CreateGeometry()
{
  //
  // Builds simple Geant3 geometry
  //
}
//_____________________________________________________________________________
void AliVZERO::CreateMaterials()
{
  //
  // Creates materials used for Geant3 geometry
  //
}

//_____________________________________________________________________________
Int_t AliVZERO::DistanceToPrimitive(Int_t /*px*/, Int_t /*py*/)
{
  //
  // Calculates the distance from the mouse to the VZERO on the screen
  // Dummy routine
  //

  return 9999;
}

//_____________________________________________________________________________
void AliVZERO::Init()
{
  //
  // Initialises the VZERO  class after it has been built
  //
}

//_____________________________________________________________________________
void AliVZERO::SetMaxStepQua(Float_t p1)
{
  //
  // Possible parametrisation of steps in active materials
  //
     fMaxStepQua = p1;
}

//_____________________________________________________________________________
void AliVZERO::SetMaxStepAlu(Float_t p1)
{
  //
  // Possible parametrisation of steps in Aluminum foils (not used in
  // version v2)
  //
    fMaxStepAlu = p1;
}

//_____________________________________________________________________________
void AliVZERO::SetMaxDestepQua(Float_t p1)
{
  //
  // Possible parametrisation of steps in active materials (quartz)
  //
    fMaxDestepQua = p1;
}

//_____________________________________________________________________________
void AliVZERO::SetMaxDestepAlu(Float_t p1)
{
  //
  // Possible parametrisation of steps in Aluminum (not used in
  // version v2)
  //
    fMaxDestepAlu = p1;
}

//_____________________________________________________________________________
AliLoader* AliVZERO::MakeLoader(const char* topfoldername)
{
  //
  // Builds VZEROgetter (AliLoader type)
  // if detector wants to use customized getter, it must overload this method
  //
//  Info("MakeLoader","Creating AliVZEROLoader. Top folder is %s.",topfoldername);

  AliDebug(1,Form("Creating AliVZEROLoader, Top folder is %s ",topfoldername));
  fLoader = new AliVZEROLoader(GetName(),topfoldername);
  return fLoader;
}

//_____________________________________________________________________________
void AliVZERO::SetTreeAddress()
{
  //
  // Sets tree address for hits.
  //
  if (fLoader->TreeH() && (fHits == 0x0))
    fHits = new  TClonesArray("AliVZEROhit", 400);

  AliDetector::SetTreeAddress();
}

//_____________________________________________________________________________
AliDigitizer* AliVZERO::CreateDigitizer(AliRunDigitizer* manager) const
{
  //
  // Creates a digitizer for VZERO
  //
  return new AliVZERODigitizer(manager);
}

//_____________________________________________________________________________
void AliVZERO::Hits2Digits(){
  //
  // Converts hits to digits of the current event
  //
  // Inputs file name
  const char *alifile = "galice.root";

  // Create the run digitizer
  AliRunDigitizer* manager = new AliRunDigitizer(1, 1);
  manager->SetInputStream(0, alifile);
  manager->SetOutputFile("H2Dfile");

  // Creates the VZERO digitizer
  AliVZERODigitizer* dig = new AliVZERODigitizer(manager);

  // Creates the digits
  dig->Exec("");

}
//_____________________________________________________________________________
void AliVZERO::Digits2Raw()
{
  //
  // Converts digits of the current event to raw data
  //
  AliVZERO *fVZERO = (AliVZERO*)gAlice->GetDetector("VZERO");
  fLoader->LoadDigits();
  TTree* digits = fLoader->TreeD();
  if (!digits) {
    Error("Digits2Raw", "no digits tree");
    return;
  }
  TClonesArray * VZEROdigits = new TClonesArray("AliVZEROdigit",1000);
  fVZERO->SetTreeAddress();
  digits->GetBranch("VZERODigit")->SetAddress(&VZEROdigits);

  const char *fileName    = AliDAQ::DdlFileName("VZERO",0);
  AliVZEROBuffer* buffer  = new AliVZEROBuffer(fileName);

  //  Verbose level
  //  0: Silent
  //  1: cout messages
  //  2: txt files with digits
  //  BE CAREFUL, verbose level 2 MUST be used only for debugging and
  //  it is highly suggested to use this mode only for debugging digits files
  //  reasonably small, because otherwise the size of the txt files can reach
  //  quickly several MB wasting time and disk space.

  ofstream ftxt;
  buffer->SetVerbose(0);
  Int_t verbose = buffer->GetVerbose();

  // Get Trigger information first
  // Read trigger inputs from trigger-detector object
  AliDataLoader * dataLoader = fLoader->GetDigitsDataLoader();
  if( !dataLoader->IsFileOpen() )
    dataLoader->OpenFile( "READ" );
  AliTriggerDetector* trgdet = (AliTriggerDetector*)dataLoader->GetDirectory()->Get( "Trigger" );
  UInt_t triggerInfo = 0;
  if(trgdet) {
    triggerInfo = trgdet->GetMask() & 0xffff;
  }
  else {
    AliError(Form("There is no trigger object for %s",fLoader->GetName()));
  }
  buffer->WriteTriggerInfo((UInt_t)triggerInfo);

  // Now write the channel information: charge+time
  // We assume here an ordered (by PMNumber) array of
  // digits!!
  Int_t nEntries = Int_t(digits->GetEntries());
  for (Int_t i = 0; i < nEntries; i++) {

    fVZERO->ResetDigits();
    digits->GetEvent(i);
    Int_t ndig = VZEROdigits->GetEntriesFast();

    if(ndig == 0) continue;
    if(verbose == 2) {ftxt.open("VZEROdigits.txt",ios::app);}
    for(Int_t k=0; k<ndig; k++){
        AliVZEROdigit* fVZERODigit = (AliVZEROdigit*) VZEROdigits->At(k);
	Int_t ADC       = fVZERODigit->ADC();
	Int_t PMNumber  = fVZERODigit->PMNumber();
	Int_t Time      = fVZERODigit->Time();
        if(verbose == 1) { cout <<"DDL: "<<fileName<< "\tdigit number: "<< k<<"\tPM number: "
	                    <<PMNumber<<"\tADC: "<< ADC << "\tTime: "<< Time << endl;}
	if(verbose == 2) {
	    ftxt<<"DDL: "<<fileName<< "\tdigit number: "<< k<<"\tPM number: "
	                   <<PMNumber<<"\tADC: "<< ADC << "\tTime: "<< Time << endl;
	}
        buffer->WriteChannel(PMNumber, ADC, Time);
    }
  if(verbose==2) ftxt.close();
  }

  buffer->WriteScalers();
  buffer->WriteMBInfo();

  delete buffer;
  fLoader->UnloadDigits();
}

//_____________________________________________________________________________
Bool_t AliVZERO::Raw2SDigits(AliRawReader* rawReader){
  // Converts the VZERO raw data into digits
  // The method is used for merging simulated and
  // real data events
  TStopwatch timer;
  timer.Start();

  if(!fLoader) {
    AliError("no VZERO loader found");
    return kFALSE; }

  TTree* treeD  = fLoader->TreeD();
  if(!treeD) {
      fLoader->MakeTree("D");
      treeD = fLoader->TreeD(); }

  AliVZEROdigit  digit;
  AliVZEROdigit* pdigit = &digit;
  const Int_t kBufferSize = 4000;

  treeD->Branch("VZERO", "AliVZEROdigit",  &pdigit, kBufferSize);

  rawReader->Reset();
  AliVZERORawStream* rawStream  = new AliVZERORawStream(rawReader);

  if (!rawStream->Next()) return kFALSE; // No VZERO data found

  for(Int_t i=0; i<64; i++) {
      new(pdigit) AliVZEROdigit(i, (Int_t)rawStream->GetADC(i), (Int_t)rawStream->GetTime(i));
      treeD->Fill();
  }

// Checks if everything is OK by printing results

//   for(int i=0;i<64;i++) {
// 	printf("Channel %d : %d %d \n",i,rawStream->GetADC(i),rawStream->GetTime(i)); }
//   treeD->Print(); printf(" \n");

  fLoader->WriteDigits("OVERWRITE");
  fLoader->UnloadDigits();

  delete rawStream;

  timer.Stop();
  timer.Print();
}

<commit_msg>New Raw Data format implemented<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.                  *
 **************************************************************************/

/* $Id$ */

///////////////////////////////////////////////////////////////////////////
//                                                                       //
//                          V-Zero   Detector                            //
//  This class contains the base procedures for the VZERO  detector      //
//  Default geometry of November 2003 :   V0R box is 4.4 cm thick        //
//                                  scintillators are 2 cm thick         //
//  All comments should be sent to Brigitte CHEYNIS :                    //
//                                 b.cheynis@ipnl.in2p3.fr               //
//                                                                       //
//                                                                       //
///////////////////////////////////////////////////////////////////////////

// --- Standard libraries ---
#include <Riostream.h>
#include <stdlib.h>

// --- ROOT libraries ---
#include <TNamed.h>
#include "TROOT.h"
#include "TFile.h"
#include "TNetFile.h"
#include "TRandom.h"
#include "TTree.h"
#include "TBranch.h"
#include "TClonesArray.h"
#include "TStopwatch.h"

// --- AliRoot header files ---
#include "AliRun.h"
#include "AliMC.h"
#include "AliVZERO.h"
#include "AliVZEROLoader.h"
#include "AliVZERODigitizer.h"
#include "AliVZEROBuffer.h"
#include "AliRunDigitizer.h"
#include "AliVZEROdigit.h"
#include "AliDAQ.h"
#include "AliRawReader.h"
#include "AliVZERORawStream.h"

ClassImp(AliVZERO)
 //__________________________________________________________________
AliVZERO::AliVZERO(): AliDetector(),
          fIdSens1(0),
          fThickness(0.),
	  fThickness1(0.),
	  fMaxStepQua(0.),
	  fMaxStepAlu(0.),
	  fMaxDestepQua(0.),
	  fMaxDestepAlu(0.)
{
/// Default Constructor

    AliDebug(1,Form("default (empty) ctor this=%p",this));
    fIshunt          = 0;
}
//_____________________________________________________________________________
AliVZERO::AliVZERO(const char *name, const char *title)
       : AliDetector(name,title),
         fIdSens1(0),
         fThickness(4.4),
	 fThickness1(2.0),
	 fMaxStepQua(0.05),
	 fMaxStepAlu(0.01),
	 fMaxDestepQua(-1.0),
	 fMaxDestepAlu(-1.0)
{

  // Standard constructor for VZERO Detector

  AliDebug(1,Form("ctor this=%p",this));

  //  fIshunt       =  1;  // All hits are associated with primary particles

  fHits         =  new TClonesArray("AliVZEROhit", 400);
  fDigits       =  new TClonesArray("AliVZEROdigit",400);

  gAlice->GetMCApp()->AddHitList(fHits);

//   fThickness    =  4.4;   // total thickness of the V0R box in cm
//   fThickness1   =  2.0;   // thickness of scintillating cells in cm
//
//   fMaxStepQua   =  0.05;
//   fMaxStepAlu   =  0.01;
//
//   fMaxDestepQua =  -1.0;
//   fMaxDestepAlu =  -1.0;

}

//_____________________________________________________________________________
AliVZERO::~AliVZERO()
{
  //
  // Default destructor for VZERO Detector
  //

    if (fHits) {
        fHits->Delete();
        delete fHits;
	fHits=0; }

    if (fDigits) {
        fDigits->Delete();
        delete fDigits;
        fDigits=0; }
}

//_____________________________________________________________________________
void AliVZERO::BuildGeometry()
{
  //
  // Builds simple ROOT TNode geometry for event display
  //
}

//_____________________________________________________________________________
void AliVZERO::CreateGeometry()
{
  //
  // Builds simple Geant3 geometry
  //
}
//_____________________________________________________________________________
void AliVZERO::CreateMaterials()
{
  //
  // Creates materials used for Geant3 geometry
  //
}

//_____________________________________________________________________________
Int_t AliVZERO::DistanceToPrimitive(Int_t /*px*/, Int_t /*py*/)
{
  //
  // Calculates the distance from the mouse to the VZERO on the screen
  // Dummy routine
  //

  return 9999;
}

//_____________________________________________________________________________
void AliVZERO::Init()
{
  //
  // Initialises the VZERO  class after it has been built
  //
}

//_____________________________________________________________________________
void AliVZERO::SetMaxStepQua(Float_t p1)
{
  //
  // Possible parametrisation of steps in active materials
  //
     fMaxStepQua = p1;
}

//_____________________________________________________________________________
void AliVZERO::SetMaxStepAlu(Float_t p1)
{
  //
  // Possible parametrisation of steps in Aluminum foils (not used in
  // version v2)
  //
    fMaxStepAlu = p1;
}

//_____________________________________________________________________________
void AliVZERO::SetMaxDestepQua(Float_t p1)
{
  //
  // Possible parametrisation of steps in active materials (quartz)
  //
    fMaxDestepQua = p1;
}

//_____________________________________________________________________________
void AliVZERO::SetMaxDestepAlu(Float_t p1)
{
  //
  // Possible parametrisation of steps in Aluminum (not used in
  // version v2)
  //
    fMaxDestepAlu = p1;
}

//_____________________________________________________________________________
AliLoader* AliVZERO::MakeLoader(const char* topfoldername)
{
  //
  // Builds VZEROgetter (AliLoader type)
  // if detector wants to use customized getter, it must overload this method
  //
//  Info("MakeLoader","Creating AliVZEROLoader. Top folder is %s.",topfoldername);

  AliDebug(1,Form("Creating AliVZEROLoader, Top folder is %s ",topfoldername));
  fLoader = new AliVZEROLoader(GetName(),topfoldername);
  return fLoader;
}

//_____________________________________________________________________________
void AliVZERO::SetTreeAddress()
{
  //
  // Sets tree address for hits.
  //
  if (fLoader->TreeH() && (fHits == 0x0))
    fHits = new  TClonesArray("AliVZEROhit", 400);

  AliDetector::SetTreeAddress();
}

//_____________________________________________________________________________
AliDigitizer* AliVZERO::CreateDigitizer(AliRunDigitizer* manager) const
{
  //
  // Creates a digitizer for VZERO
  //
  return new AliVZERODigitizer(manager);
}

//_____________________________________________________________________________
void AliVZERO::Hits2Digits(){
  //
  // Converts hits to digits of the current event
  //
  // Inputs file name
  const char *alifile = "galice.root";

  // Create the run digitizer
  AliRunDigitizer* manager = new AliRunDigitizer(1, 1);
  manager->SetInputStream(0, alifile);
  manager->SetOutputFile("H2Dfile");

  // Creates the VZERO digitizer
  AliVZERODigitizer* dig = new AliVZERODigitizer(manager);

  // Creates the digits
  dig->Exec("");

}
//_____________________________________________________________________________
void AliVZERO::Digits2Raw()
{
   //
   //  Converts digits of the current event to raw data
   //

   AliVZERO *fVZERO = (AliVZERO*)gAlice->GetDetector("VZERO");
   fLoader->LoadDigits();
   TTree* digits = fLoader->TreeD();
   if (!digits) {
      Error("Digits2Raw", "no digits tree");
      return;
   }
   TClonesArray * VZEROdigits = new TClonesArray("AliVZEROdigit",1000);
   fVZERO->SetTreeAddress();
   digits->GetBranch("VZERODigit")->SetAddress(&VZEROdigits);

   const char *fileName    = AliDAQ::DdlFileName("VZERO",0);
   AliVZEROBuffer* buffer  = new AliVZEROBuffer(fileName);

   //  Verbose level
   //  0: Silent
   //  1: cout messages
   //  2: txt files with digits
   //  BE CAREFUL, verbose level 2 MUST be used only for debugging and
   //  it is highly suggested to use this mode only for debugging digits files
   //  reasonably small, because otherwise the size of the txt files can reach
   //  quickly several MB wasting time and disk space.

   ofstream ftxt;
   buffer->SetVerbose(0);
   Int_t verbose = buffer->GetVerbose();

   // Get Trigger information first
   // Read trigger inputs from trigger-detector object
   AliDataLoader * dataLoader = fLoader->GetDigitsDataLoader();
   if( !dataLoader->IsFileOpen() )
        dataLoader->OpenFile( "READ" );
   AliTriggerDetector* trgdet = (AliTriggerDetector*)dataLoader->GetDirectory()->Get( "Trigger" );
   UInt_t triggerInfo = 0;
   if(trgdet) {
      triggerInfo = trgdet->GetMask() & 0xffff;
   }
   else {
      AliError(Form("There is no trigger object for %s",fLoader->GetName()));
   }

   buffer->WriteTriggerInfo((UInt_t)triggerInfo);
   buffer->WriteTriggerScalers();
   buffer->WriteBunchNumbers();

   // Now retrieve the channel information: charge+time and
   // dump it into ADC and Time arrays
   // We assume here an ordered (by PMNumber) array of
   // digits!!

   Int_t nEntries = Int_t(digits->GetEntries());
   UInt_t ADC[64];
   Int_t PMNumber[64];
   UInt_t Time[64];

   for (Int_t i = 0; i < nEntries; i++) {
     fVZERO->ResetDigits();
     digits->GetEvent(i);
     Int_t ndig = VZEROdigits->GetEntriesFast();

     if(ndig == 0) continue;
     if(verbose == 2) {ftxt.open("VZEROdigits.txt",ios::app);}
     for(Int_t k=0; k<ndig; k++){
         AliVZEROdigit* fVZERODigit = (AliVZEROdigit*) VZEROdigits->At(k);
	 ADC[k]       = (UInt_t) fVZERODigit->ADC();
	 PMNumber[k]  = fVZERODigit->PMNumber();
	 Time[k]      = (UInt_t) fVZERODigit->Time();
         if(verbose == 1) { cout <<"DDL: "<<fileName<< "\tdigit number: "<< k<<"\tPM number: "
	                    <<PMNumber[k]<<"\tADC: "<< ADC[k] << "\tTime: "<< Time[k] << endl;}
	 if(verbose == 2) {
	      ftxt<<"DDL: "<<fileName<< "\tdigit number: "<< k<<"\tPM number: "
	                   <<PMNumber[k]<<"\tADC: "<< ADC[k] << "\tTime: "<< Time[k] << endl;}
//	 printf("DDL: %s, channel: %d, PM: %d, ADC: %d, Time: %d \n",
//	            fileName,k,PMNumber[k],ADC[k],Time[k]);
     }
   if(verbose==2) ftxt.close();
   }

   // Now fill raw data

   for (Int_t  iCIU = 0; iCIU < 8; iCIU++) {

   // decoding of one Channel Interface Unit numbered iCIU - there are 8 channels per CIU (and 8 CIUs) :

      for(Int_t iChannel_Offset = iCIU*8; iChannel_Offset < (iCIU*8)+8; iChannel_Offset=iChannel_Offset+4) {
         for(Int_t iChannel = iChannel_Offset; iChannel < iChannel_Offset+4; iChannel++) {
             buffer->WriteChannel(iChannel, ADC[iChannel], Time[iChannel]);
         }
         buffer->WriteBeamFlags();
         buffer->WriteMBInfo();
         buffer->WriteMBFlags();
         buffer->WriteBeamScalers();
      }
      for(Int_t kChannel = kChannel=0; kChannel < 8; kChannel++) {
          buffer->WriteTiming(kChannel, ADC[kChannel], Time[kChannel]);
      }

    // End of decoding of one CIU card

  } // end of decoding the eight CIUs

  delete buffer;
  fLoader->UnloadDigits();
}

//_____________________________________________________________________________
Bool_t AliVZERO::Raw2SDigits(AliRawReader* rawReader){
  // Converts the VZERO raw data into digits
  // The method is used for merging simulated and
  // real data events
  TStopwatch timer;
  timer.Start();

  if(!fLoader) {
    AliError("no VZERO loader found");
    return kFALSE; }

  TTree* treeD  = fLoader->TreeD();
  if(!treeD) {
      fLoader->MakeTree("D");
      treeD = fLoader->TreeD(); }

  AliVZEROdigit  digit;
  AliVZEROdigit* pdigit = &digit;
  const Int_t kBufferSize = 4000;

  treeD->Branch("VZERO", "AliVZEROdigit",  &pdigit, kBufferSize);

  rawReader->Reset();
  AliVZERORawStream* rawStream  = new AliVZERORawStream(rawReader);

  if (!rawStream->Next()) return kFALSE; // No VZERO data found

  for(Int_t i=0; i<64; i++) {
      new(pdigit) AliVZEROdigit(i, (Int_t)rawStream->GetADC(i), (Int_t)rawStream->GetTime(i));
      treeD->Fill();
  }

// Checks if everything is OK by printing results

//   for(int i=0;i<64;i++) {
// 	printf("Channel %d : %d %d \n",i,rawStream->GetADC(i),rawStream->GetTime(i)); }
//   treeD->Print(); printf(" \n");

  fLoader->WriteDigits("OVERWRITE");
  fLoader->UnloadDigits();

  delete rawStream;

  timer.Stop();
  timer.Print();
}

<|endoftext|>


<commit_before>/*
 Copyright 2013,2014 Marko Dimjašević, Simone Atzeni, Ivo Ugrina, Zvonimir Rakamarić

 This file is part of maline.

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

 maline is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU Affero General Public License for more details.

 You should have received a copy of the GNU Affero General Public License
 along with maline.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <stdio.h>
#include <iostream>
#include <vector>
#include <string>
#include <fstream>
#include <sstream>
#include <set>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/lexical_cast.hpp>

using namespace boost::algorithm;

int main(int argc, char **argv)
{
  int N;
  std::set<int> index_set;
  int fold;

  std::string line;

  if(argc < 4) {
    printf("Usage: %s FILENAME INDEXES FOLD\n", argv[0]);
    exit(-1);
  }

  std::istringstream buffer(argv[3]);
  buffer >> fold;

  std::string filename1(argv[1]);
  std::stringstream s1;
  s1 << fold;
  filename1.append(".training." + s1.str());
  std::ofstream training_file(filename1.c_str());
  if(!training_file.is_open()) {
    std::cerr << "Couldn't open " << filename1 << std::endl;
    exit(-1);
  }

  std::string filename2(argv[1]);
  std::stringstream s2;
  s2 << fold;
  filename2.append(".testing." + s2.str());
  std::ofstream testing_file(filename2.c_str());
  if(!testing_file.is_open()) {
    std::cerr << "Couldn't open " << filename2 << std::endl;
    exit(-1);
  }

  std::ifstream indexes(argv[2], std::ios_base::in);
  boost::iostreams::filtering_istream in3;
  in3.push(indexes);
  for(; std::getline(in3, line); ) {
    std::cout << "Processed line " << line << "\n";
    std::vector<std::string> tokens;
    split(tokens, line, is_any_of(","));

    int index;
    std::istringstream buffer(tokens[fold - 1]);
    buffer >> index;

    index_set.insert(index);
  }

  std::ifstream file2(argv[1], std::ios_base::in);
  boost::iostreams::filtering_istream in2;
  in2.push(file2);

  int i = 1;
  for(; std::getline(in2, line); ) {
    if(index_set.find(i) != index_set.end()) {
      testing_file << line << "\n";
    } else {
      training_file << line << "\n";
    }
    i++;
  }

  training_file.close();
  testing_file.close();

  return 0;
}
<commit_msg>Fixed script to create datasets<commit_after>/*
 Copyright 2013,2014 Marko Dimjašević, Simone Atzeni, Ivo Ugrina, Zvonimir Rakamarić

 This file is part of maline.

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

 maline is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU Affero General Public License for more details.

 You should have received a copy of the GNU Affero General Public License
 along with maline.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <stdio.h>
#include <iostream>
#include <vector>
#include <string>
#include <fstream>
#include <sstream>
#include <set>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/lexical_cast.hpp>

using namespace boost::algorithm;

int main(int argc, char **argv)
{
  int N;
  std::set<int> index_set;
  int fold;

  std::string line;

  if(argc < 4) {
    printf("Usage: %s FILENAME INDEXES FOLD\n", argv[0]);
    exit(-1);
  }

  std::istringstream buffer(argv[3]);
  buffer >> fold;

  std::string filename1(argv[1]);
  std::stringstream s1;
  s1 << fold;
  filename1.append(".training." + s1.str());
  std::ofstream training_file(filename1.c_str());
  if(!training_file.is_open()) {
    std::cerr << "Couldn't open " << filename1 << std::endl;
    exit(-1);
  }

  std::string filename2(argv[1]);
  std::stringstream s2;
  s2 << fold;
  filename2.append(".testing." + s2.str());
  std::ofstream testing_file(filename2.c_str());
  if(!testing_file.is_open()) {
    std::cerr << "Couldn't open " << filename2 << std::endl;
    exit(-1);
  }

  std::ifstream indexes(argv[2], std::ios_base::in);
  boost::iostreams::filtering_istream in3;
  in3.push(indexes);
  for(; std::getline(in3, line); ) {
    // std::cout << "Processed line " << line << "\n";
    std::vector<std::string> tokens;
    split(tokens, line, is_any_of(","));

    int index;
    std::istringstream buffer(tokens[fold - 1]);
    buffer >> index;

    index_set.insert(index);
  }

  std::ifstream file2(argv[1], std::ios_base::in);
  boost::iostreams::filtering_istream in2;
  in2.push(file2);

  int i = 1;
  for(; std::getline(in2, line); ) {
    if(index_set.find(i) != index_set.end()) {
      testing_file << line << "\n";
    } else {
      training_file << line << "\n";
    }
    i++;
  }

  training_file.close();
  testing_file.close();

  return 0;
}
<|endoftext|>


<commit_before>
#include <core/map/map1.h>
#include <core/map/map2.h>

#include <core/basic/dart_marker.h>
#include <core/basic/cell_marker.h>

using namespace cgogn;

struct My_Data_Traits
{
	static const unsigned int CHUNK_SIZE = 64;
};

// typedefs for short writing
typedef Map1<My_Data_Traits> MAP1;
typedef Map2<My_Data_Traits> MAP2;

void fonc_const(const MAP1::VertexAttributeHandler<float>& ah);
void fonc_non_const(MAP1::VertexAttributeHandler<float>& ah);
int test1(MAP1& map);

void fonc_const(const MAP1::VertexAttributeHandler<float>& ah)
{
	for (const float& f:ah)
	{
		std::cout << f << std::endl;
	}

	// equivalent to
	for (MAP1::VertexAttributeHandler<float>::const_iterator it = ah.begin(); it != ah.end(); ++it)
		std::cout << *it << std::endl;
}

void fonc_non_const(MAP1::VertexAttributeHandler<float>& ah)
{
	for (float& f:ah)
	{
		f *= 2.0f;
		std::cout << f << std::endl;
	}

	// equivalent to
	for (MAP1::VertexAttributeHandler<float>::iterator it = ah.begin(); it != ah.end(); ++it)
	{
		*it /= 2.0f;
	}
}

int test1(MAP1& map)
{
	// add an attribute on vertex of map with
	MAP1::VertexAttributeHandler<float> ah = map.add_attribute<float, MAP1::VERTEX>("floats");

	std::vector<unsigned int>* uib = cgogn::getUINTBuffers()->get_buffer();
	uib->push_back(3);
	cgogn::getUINTBuffers()->release_buffer(uib);

	Dart d = map.add_dart();

	DartMarker<MAP1> dm(map);
	CellMarker<MAP1, MAP1::VERTEX> cm(map);

	dm.mark(d);

	std::cout << "Darts :" << std::endl;
	for (Dart dit : map)
	{
		std::cout << dit << std::endl;
	}

	// get ChunkArrayContainer -> get ChunkArray -> fill
	ChunkArrayContainer<My_Data_Traits::CHUNK_SIZE, unsigned int>& container = map.get_attribute_container(VERTEX1);
	ChunkArray<My_Data_Traits::CHUNK_SIZE,float>* att = container.get_attribute<float>("floats");
	for (int i=0;i<10;++i)
		container.insert_lines<1>();
	for(unsigned int i=container.begin(); i!=container.end(); container.next(i))
		(*att)[i] = 3.0f + 0.1f*float(i);

	// access with index
	std::cout << ah[0] << std::endl;

	fonc_non_const(ah);

	fonc_const(ah);

	//	// traverse container with for range
	//	for (float f:ah)
	//		std::cout << f << std::endl;

	return 0;
}

int main()
{
	cgogn::thread_start();
	MAP1 map1;
	MAP2 map2;
	test1(map1);
	//cgogn::thread_stop();
	return 0;
}
<commit_msg>small fix.<commit_after>
#include <core/map/map1.h>
#include <core/map/map2.h>

#include <core/basic/dart_marker.h>
#include <core/basic/cell_marker.h>

using namespace cgogn;

struct My_Data_Traits
{
	static const unsigned int CHUNK_SIZE = 64;
};

// typedefs for short writing
typedef Map1<My_Data_Traits> MAP1;
typedef Map2<My_Data_Traits> MAP2;

void fonc_const(const MAP1::VertexAttributeHandler<float>& ah);
void fonc_non_const(MAP1::VertexAttributeHandler<float>& ah);
int test1(MAP1& map);

void fonc_const(const MAP1::VertexAttributeHandler<float>& ah)
{
	for (const float& f:ah)
	{
		std::cout << f << std::endl;
	}

	// equivalent to
	for (MAP1::VertexAttributeHandler<float>::const_iterator it = ah.begin(); it != ah.end(); ++it)
		std::cout << *it << std::endl;
}

void fonc_non_const(MAP1::VertexAttributeHandler<float>& ah)
{
	for (float& f:ah)
	{
		f *= 2.0f;
		std::cout << f << std::endl;
	}

	// equivalent to
	for (MAP1::VertexAttributeHandler<float>::iterator it = ah.begin(); it != ah.end(); ++it)
	{
		*it /= 2.0f;
	}
}

int test1(MAP1& map)
{
	// add an attribute on vertex of map with
	MAP1::VertexAttributeHandler<float> ah = map.add_attribute<float, MAP1::VERTEX>("floats");

	std::vector<unsigned int>* uib = cgogn::getUINTBuffers()->get_buffer();
	uib->push_back(3);
	cgogn::getUINTBuffers()->release_buffer(uib);

	Dart d = map.add_dart();

	DartMarker<MAP1> dm(map);
	CellMarker<MAP1, MAP1::VERTEX> cm(map);

	dm.mark(d);

	std::cout << "Darts :" << std::endl;
	for (Dart dit : map)
	{
		std::cout << dit << std::endl;
	}

	// get ChunkArrayContainer -> get ChunkArray -> fill
	ChunkArrayContainer<My_Data_Traits::CHUNK_SIZE, unsigned int>& container = map.get_attribute_container(VERTEX1);
	ChunkArray<My_Data_Traits::CHUNK_SIZE,float>* att = container.get_attribute<float>("floats");
	for (int i=0;i<10;++i)
		container.insert_lines<1>();
	for(unsigned int i=container.begin(); i!=container.end(); container.next(i))
		(*att)[i] = 3.0f + 0.1f*float(i);

	// access with index
	std::cout << ah[0] << std::endl;

	fonc_non_const(ah);

	fonc_const(ah);

	//	// traverse container with for range
	//	for (float f:ah)
	//		std::cout << f << std::endl;

	return 0;
}

int main()
{
	cgogn::thread_start();
	MAP1 map1;
	MAP2 map2;
	test1(map1);
	cgogn::thread_stop();
	return 0;
}
<|endoftext|>


<commit_before>// For conditions of distribution and use, see copyright notice in LICENSE

#include "Framework.h"
#include "TundraCoreApi.h"
#include "Win.h"

int TUNDRACORE_API run(int argc, char **argv);

#ifdef ANDROID
#include "StaticPluginRegistry.h"
/// \todo Eliminate the need to list static plugins explicitly here
REGISTER_STATIC_PLUGIN(OgreRenderingModule)
REGISTER_STATIC_PLUGIN(PhysicsModule)
REGISTER_STATIC_PLUGIN(EnvironmentModule)
REGISTER_STATIC_PLUGIN(TundraLogicModule)
REGISTER_STATIC_PLUGIN(AssetModule)
REGISTER_STATIC_PLUGIN(JavascriptModule)
REGISTER_STATIC_PLUGIN(AvatarModule)
REGISTER_STATIC_PLUGIN(DebugStatsModule)
#endif

#ifdef _WIN64#ifdef _WIN64 // Use kNet's BottomMemoryAllocator on to catch potential 64-bit memory allocation bugs early on.
#include <kNet/64BitAllocDebugger.h>
BottomMemoryAllocator bma;
#endif

#if defined(_MSC_VER) // Windows application entry point.
int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, LPSTR lpCmdLine, int /*nShowCmd*/){
    std::string cmdLine(lpCmdLine);

    // Parse the Windows command line.
    std::vector<std::string> arguments;
    unsigned i;
    unsigned cmdStart = 0;
    unsigned cmdEnd = 0;
    bool cmd = false;
    bool quote = false;

    // Inject executable name as Framework will expect it to be there.
    // Otherwise the first param will be ignored (it assumes its the executable name).
    // In WinMain() its not included in the 'lpCmdLine' param.
    arguments.push_back("Tundra.exe");

    for(i = 0; i < cmdLine.length(); ++i)
    {
        if (cmdLine[i] == '\"')
            quote = !quote;
        if ((cmdLine[i] == ' ') && (!quote))
        {
            if (cmd)
            {
                cmd = false;
                cmdEnd = i;
                arguments.push_back(cmdLine.substr(cmdStart, cmdEnd-cmdStart));
            }
        }
        else
        {
            if (!cmd)
            {
               cmd = true;
               cmdStart = i;
            }
        }
    }
    if (cmd)
        arguments.push_back(cmdLine.substr(cmdStart, i-cmdStart));

    std::vector<const char*> argv;
    for(size_t i = 0; i < arguments.size(); ++i)
        argv.push_back(arguments[i].c_str());

    if (argv.size())
        return run((int)argv.size(), (char**)&argv[0]);
    else
        return run(0, 0);
}
#else // Unix entry point
int main(int argc, char **argv)
{
    return run(argc, argv);
}
#endif

<commit_msg>Fix copy-paste bug.<commit_after>// For conditions of distribution and use, see copyright notice in LICENSE

#include "Framework.h"
#include "TundraCoreApi.h"
#include "Win.h"

int TUNDRACORE_API run(int argc, char **argv);

#ifdef ANDROID
#include "StaticPluginRegistry.h"
/// \todo Eliminate the need to list static plugins explicitly here
REGISTER_STATIC_PLUGIN(OgreRenderingModule)
REGISTER_STATIC_PLUGIN(PhysicsModule)
REGISTER_STATIC_PLUGIN(EnvironmentModule)
REGISTER_STATIC_PLUGIN(TundraLogicModule)
REGISTER_STATIC_PLUGIN(AssetModule)
REGISTER_STATIC_PLUGIN(JavascriptModule)
REGISTER_STATIC_PLUGIN(AvatarModule)
REGISTER_STATIC_PLUGIN(DebugStatsModule)
#endif

#ifdef _WIN64 // Use kNet's BottomMemoryAllocator on to catch potential 64-bit memory allocation bugs early on.
#include <kNet/64BitAllocDebugger.h>
BottomMemoryAllocator bma;
#endif

#if defined(_MSC_VER) // Windows application entry point.
int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, LPSTR lpCmdLine, int /*nShowCmd*/){
    std::string cmdLine(lpCmdLine);

    // Parse the Windows command line.
    std::vector<std::string> arguments;
    unsigned i;
    unsigned cmdStart = 0;
    unsigned cmdEnd = 0;
    bool cmd = false;
    bool quote = false;

    // Inject executable name as Framework will expect it to be there.
    // Otherwise the first param will be ignored (it assumes its the executable name).
    // In WinMain() its not included in the 'lpCmdLine' param.
    arguments.push_back("Tundra.exe");

    for(i = 0; i < cmdLine.length(); ++i)
    {
        if (cmdLine[i] == '\"')
            quote = !quote;
        if ((cmdLine[i] == ' ') && (!quote))
        {
            if (cmd)
            {
                cmd = false;
                cmdEnd = i;
                arguments.push_back(cmdLine.substr(cmdStart, cmdEnd-cmdStart));
            }
        }
        else
        {
            if (!cmd)
            {
               cmd = true;
               cmdStart = i;
            }
        }
    }
    if (cmd)
        arguments.push_back(cmdLine.substr(cmdStart, i-cmdStart));

    std::vector<const char*> argv;
    for(size_t i = 0; i < arguments.size(); ++i)
        argv.push_back(arguments[i].c_str());

    if (argv.size())
        return run((int)argv.size(), (char**)&argv[0]);
    else
        return run(0, 0);
}
#else // Unix entry point
int main(int argc, char **argv)
{
    return run(argc, argv);
}
#endif

<|endoftext|>


<commit_before><commit_msg>Update ReadDICOM.cxx<commit_after><|endoftext|>


<commit_before>#define PUT(x) std::cout << #x "=" << (x) << std::endl
#include <cybozu/test.hpp>
#include <cybozu/benchmark.hpp>
#include <time.h>

#include <mcl/fp.hpp>
struct ZnTag;
typedef mcl::FpT<ZnTag> Zn;
typedef mcl::FpT<> Fp;

struct Montgomery {
	typedef mcl::fp::Unit Unit;
	mpz_class p_;
	mpz_class R_; // (1 << (pn_ * 64)) % p
	mpz_class RR_; // (R * R) % p
	Unit rp_; // rp * p = -1 mod M = 1 << 64
	size_t pn_;
	Montgomery() {}
	explicit Montgomery(const mpz_class& p)
	{
		p_ = p;
		rp_ = mcl::fp::getMontgomeryCoeff(mcl::gmp::getUnit(p, 0));
		pn_ = mcl::gmp::getUnitSize(p);
		R_ = 1;
		R_ = (R_ << (pn_ * 64)) % p_;
		RR_ = (R_ * R_) % p_;
	}

	void toMont(mpz_class& x) const { mul(x, x, RR_); }
	void fromMont(mpz_class& x) const { mul(x, x, 1); }

	void mul(mpz_class& z, const mpz_class& x, const mpz_class& y) const
	{
#if 0
		const size_t ySize = mcl::gmp::getUnitSize(y);
		mpz_class c = x * mcl::gmp::getUnit(y, 0);
		Unit q = mcl::gmp::getUnit(c, 0) * rp_;
		c += p_ * q;
		c >>= sizeof(Unit) * 8;
		for (size_t i = 1; i < pn_; i++) {
			if (i < ySize) {
				c += x * mcl::gmp::getUnit(y, i);
			}
			Unit q = mcl::gmp::getUnit(c, 0) * rp_;
			c += p_ * q;
			c >>= sizeof(Unit) * 8;
		}
		if (c >= p_) {
			c -= p_;
		}
		z = c;
#else
		z = x * y;
		for (size_t i = 0; i < pn_; i++) {
			Unit q = mcl::gmp::getUnit(z, 0) * rp_;
#ifdef MCL_USE_VINT
			z += p_ * q;
#else
			z += p_ * (mp_limb_t)q;
#endif
			z >>= sizeof(Unit) * 8;
		}
		if (z >= p_) {
			z -= p_;
		}
#endif
	}
};

template<class T>
mpz_class getMpz(const T& x)
{
	std::string str = x.getStr();
	mpz_class t;
	mcl::gmp::setStr(t, str);
	return t;
}

template<class T>
std::string getStr(const T& x)
{
	std::ostringstream os;
	os << x;
	return os.str();
}

template<class T, class U>
T castTo(const U& x)
{
	T t;
	t.setStr(getStr(x));
	return t;
}

template<class T>
void putRaw(const T& x)
{
	const uint64_t *p = x.getInnerValue();
	for (size_t i = 0, n = T::BlockSize; i < n; i++) {
		printf("%016llx", p[n - 1 - i]);
	}
	printf("\n");
}

template<size_t N>
void put(const uint64_t (&x)[N])
{
	for (size_t i = 0; i < N; i++) {
		printf("%016llx", x[N - 1 - i]);
	}
	printf("\n");
}

struct Test {
	typedef mcl::FpT<> Fp;
	void run(const char *p)
	{
		Fp::init(p);
		Fp x("-123456789");
		Fp y("-0x7ffffffff");
		CYBOZU_BENCH("add", operator+, x, x);
		CYBOZU_BENCH("sub", operator-, x, y);
		CYBOZU_BENCH("mul", operator*, x, x);
		CYBOZU_BENCH("sqr", Fp::sqr, x, x);
		CYBOZU_BENCH("div", y += x; operator/, x, y);
	}
};

void customTest(const char *pStr, const char *xStr, const char *yStr)
{
#if 0
	{
		pStr = "0xfffffffffffffffffffffffffffffffffffffffeffffee37",
		Fp::init(pStr);
		static uint64_t x[3] = { 1, 0, 0 };
		uint64_t z[3];
std::cout<<std::hex;
		Fp::inv(*(Fp*)z, *(const Fp*)x);
put(z);
		exit(1);
	}
#endif
#if 0
	std::cout << std::hex;
	uint64_t x[9] = { 0xff7fffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x1ff };
	uint64_t y[9] = { 0xff7fffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x1ff };
	uint64_t z1[9], z2[9];
	Fp::init(pStr);
	Fp::fg_.mul_(z2, x, y);
	put(z2);
	{
		puts("C");
		mpz_class p(pStr);
		Montgomery mont(p);
		mpz_class xx, yy;
		mcl::gmp::setArray(xx, x, CYBOZU_NUM_OF_ARRAY(x));
		mcl::gmp::setArray(yy, y, CYBOZU_NUM_OF_ARRAY(y));
		mpz_class z;
		mont.mul(z, xx, yy);
		std::cout << std::hex << z << std::endl;
	}
	exit(1);
#else
	std::string rOrg, rC, rAsm;
	Zn::init(pStr);
	Zn s(xStr), t(yStr);
	s *= t;
	rOrg = getStr(s);
	{
		puts("C");
		mpz_class p(pStr);
		Montgomery mont(p);
		mpz_class x(xStr), y(yStr);
		mont.toMont(x);
		mont.toMont(y);
		mpz_class z;
		mont.mul(z, x, y);
		mont.fromMont(z);
		rC = getStr(z);
	}

	puts("asm");
	Fp::init(pStr);
	Fp x(xStr), y(yStr);
	x *= y;
	rAsm = getStr(x);
	CYBOZU_TEST_EQUAL(rOrg, rC);
	CYBOZU_TEST_EQUAL(rOrg, rAsm);
#endif
}

#if MCL_MAX_BIT_SIZE >= 521
CYBOZU_TEST_AUTO(customTest)
{
	const struct {
		const char *p;
		const char *x;
		const char *y;
	} tbl[] = {
		{
			"0x1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
//			"0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff",
//			"0xfffffffffffffffffffffffffffffffffffffffeffffee37",
			"0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe",
			"0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"
		},
	};
	for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) {
		customTest(tbl[i].p, tbl[i].x, tbl[i].y);
	}
}
#endif

CYBOZU_TEST_AUTO(test)
{
	Test test;
	const char *tbl[] = {
		// N = 2
		"0x0000000000000001000000000000000d",
		"0x7fffffffffffffffffffffffffffffff",
		"0x8000000000000000000000000000001d",
		"0xffffffffffffffffffffffffffffff61",

		// N = 3
		"0x000000000000000100000000000000000000000000000033", // min prime
		"0x00000000fffffffffffffffffffffffffffffffeffffac73",
		"0x0000000100000000000000000001b8fa16dfab9aca16b6b3",
		"0x000000010000000000000000000000000000000000000007",
		"0x30000000000000000000000000000000000000000000002b",
		"0x70000000000000000000000000000000000000000000001f",
		"0x800000000000000000000000000000000000000000000005",
		"0xfffffffffffffffffffffffffffffffffffffffeffffee37",
		"0xfffffffffffffffffffffffe26f2fc170f69466a74defd8d",
		"0xffffffffffffffffffffffffffffffffffffffffffffff13", // max prime

		// N = 4
		"0x0000000000000001000000000000000000000000000000000000000000000085", // min prime
		"0x2523648240000001ba344d80000000086121000000000013a700000000000013",
		"0x7523648240000001ba344d80000000086121000000000013a700000000000017",
		"0x800000000000000000000000000000000000000000000000000000000000005f",
		"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff43", // max prime

#if MCL_MAX_BIT_SIZE >= 384
		// N = 6
		"0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff",
#endif

#if MCL_MAX_BIT_SIZE >= 521
		// N = 9
		"0x1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
#endif
	};
	for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) {
		printf("prime=%s\n", tbl[i]);
		test.run(tbl[i]);
	}
}
<commit_msg>avoid ambigious type<commit_after>#define PUT(x) std::cout << #x "=" << (x) << std::endl
#include <cybozu/test.hpp>
#include <cybozu/benchmark.hpp>
#include <time.h>

#include <mcl/fp.hpp>
struct ZnTag;
typedef mcl::FpT<ZnTag> Zn;
typedef mcl::FpT<> Fp;

struct Montgomery {
	typedef mcl::fp::Unit Unit;
	mpz_class p_;
	mpz_class R_; // (1 << (pn_ * 64)) % p
	mpz_class RR_; // (R * R) % p
	Unit rp_; // rp * p = -1 mod M = 1 << 64
	size_t pn_;
	Montgomery() {}
	explicit Montgomery(const mpz_class& p)
	{
		p_ = p;
		rp_ = mcl::fp::getMontgomeryCoeff(mcl::gmp::getUnit(p, 0));
		pn_ = mcl::gmp::getUnitSize(p);
		R_ = 1;
		R_ = (R_ << (pn_ * 64)) % p_;
		RR_ = (R_ * R_) % p_;
	}

	void toMont(mpz_class& x) const { mul(x, x, RR_); }
	void fromMont(mpz_class& x) const { mul(x, x, 1); }

	void mul(mpz_class& z, const mpz_class& x, const mpz_class& y) const
	{
#if 0
		const size_t ySize = mcl::gmp::getUnitSize(y);
		mpz_class c = x * mcl::gmp::getUnit(y, 0);
		Unit q = mcl::gmp::getUnit(c, 0) * rp_;
		c += p_ * q;
		c >>= sizeof(Unit) * 8;
		for (size_t i = 1; i < pn_; i++) {
			if (i < ySize) {
				c += x * mcl::gmp::getUnit(y, i);
			}
			Unit q = mcl::gmp::getUnit(c, 0) * rp_;
			c += p_ * q;
			c >>= sizeof(Unit) * 8;
		}
		if (c >= p_) {
			c -= p_;
		}
		z = c;
#else
		z = x * y;
		for (size_t i = 0; i < pn_; i++) {
			Unit q = mcl::gmp::getUnit(z, 0) * rp_;
#ifdef MCL_USE_VINT
			z += p_ * q;
#else
			mpz_class t;
			mcl::gmp::set(t, q);
			z += p_ * t;
#endif
			z >>= sizeof(Unit) * 8;
		}
		if (z >= p_) {
			z -= p_;
		}
#endif
	}
};

template<class T>
mpz_class getMpz(const T& x)
{
	std::string str = x.getStr();
	mpz_class t;
	mcl::gmp::setStr(t, str);
	return t;
}

template<class T>
std::string getStr(const T& x)
{
	std::ostringstream os;
	os << x;
	return os.str();
}

template<class T, class U>
T castTo(const U& x)
{
	T t;
	t.setStr(getStr(x));
	return t;
}

template<class T>
void putRaw(const T& x)
{
	const uint64_t *p = x.getInnerValue();
	for (size_t i = 0, n = T::BlockSize; i < n; i++) {
		printf("%016llx", p[n - 1 - i]);
	}
	printf("\n");
}

template<size_t N>
void put(const uint64_t (&x)[N])
{
	for (size_t i = 0; i < N; i++) {
		printf("%016llx", x[N - 1 - i]);
	}
	printf("\n");
}

struct Test {
	typedef mcl::FpT<> Fp;
	void run(const char *p)
	{
		Fp::init(p);
		Fp x("-123456789");
		Fp y("-0x7ffffffff");
		CYBOZU_BENCH("add", operator+, x, x);
		CYBOZU_BENCH("sub", operator-, x, y);
		CYBOZU_BENCH("mul", operator*, x, x);
		CYBOZU_BENCH("sqr", Fp::sqr, x, x);
		CYBOZU_BENCH("div", y += x; operator/, x, y);
	}
};

void customTest(const char *pStr, const char *xStr, const char *yStr)
{
#if 0
	{
		pStr = "0xfffffffffffffffffffffffffffffffffffffffeffffee37",
		Fp::init(pStr);
		static uint64_t x[3] = { 1, 0, 0 };
		uint64_t z[3];
std::cout<<std::hex;
		Fp::inv(*(Fp*)z, *(const Fp*)x);
put(z);
		exit(1);
	}
#endif
#if 0
	std::cout << std::hex;
	uint64_t x[9] = { 0xff7fffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x1ff };
	uint64_t y[9] = { 0xff7fffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x1ff };
	uint64_t z1[9], z2[9];
	Fp::init(pStr);
	Fp::fg_.mul_(z2, x, y);
	put(z2);
	{
		puts("C");
		mpz_class p(pStr);
		Montgomery mont(p);
		mpz_class xx, yy;
		mcl::gmp::setArray(xx, x, CYBOZU_NUM_OF_ARRAY(x));
		mcl::gmp::setArray(yy, y, CYBOZU_NUM_OF_ARRAY(y));
		mpz_class z;
		mont.mul(z, xx, yy);
		std::cout << std::hex << z << std::endl;
	}
	exit(1);
#else
	std::string rOrg, rC, rAsm;
	Zn::init(pStr);
	Zn s(xStr), t(yStr);
	s *= t;
	rOrg = getStr(s);
	{
		puts("C");
		mpz_class p(pStr);
		Montgomery mont(p);
		mpz_class x(xStr), y(yStr);
		mont.toMont(x);
		mont.toMont(y);
		mpz_class z;
		mont.mul(z, x, y);
		mont.fromMont(z);
		rC = getStr(z);
	}

	puts("asm");
	Fp::init(pStr);
	Fp x(xStr), y(yStr);
	x *= y;
	rAsm = getStr(x);
	CYBOZU_TEST_EQUAL(rOrg, rC);
	CYBOZU_TEST_EQUAL(rOrg, rAsm);
#endif
}

#if MCL_MAX_BIT_SIZE >= 521
CYBOZU_TEST_AUTO(customTest)
{
	const struct {
		const char *p;
		const char *x;
		const char *y;
	} tbl[] = {
		{
			"0x1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
//			"0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff",
//			"0xfffffffffffffffffffffffffffffffffffffffeffffee37",
			"0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe",
			"0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"
		},
	};
	for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) {
		customTest(tbl[i].p, tbl[i].x, tbl[i].y);
	}
}
#endif

CYBOZU_TEST_AUTO(test)
{
	Test test;
	const char *tbl[] = {
		// N = 2
		"0x0000000000000001000000000000000d",
		"0x7fffffffffffffffffffffffffffffff",
		"0x8000000000000000000000000000001d",
		"0xffffffffffffffffffffffffffffff61",

		// N = 3
		"0x000000000000000100000000000000000000000000000033", // min prime
		"0x00000000fffffffffffffffffffffffffffffffeffffac73",
		"0x0000000100000000000000000001b8fa16dfab9aca16b6b3",
		"0x000000010000000000000000000000000000000000000007",
		"0x30000000000000000000000000000000000000000000002b",
		"0x70000000000000000000000000000000000000000000001f",
		"0x800000000000000000000000000000000000000000000005",
		"0xfffffffffffffffffffffffffffffffffffffffeffffee37",
		"0xfffffffffffffffffffffffe26f2fc170f69466a74defd8d",
		"0xffffffffffffffffffffffffffffffffffffffffffffff13", // max prime

		// N = 4
		"0x0000000000000001000000000000000000000000000000000000000000000085", // min prime
		"0x2523648240000001ba344d80000000086121000000000013a700000000000013",
		"0x7523648240000001ba344d80000000086121000000000013a700000000000017",
		"0x800000000000000000000000000000000000000000000000000000000000005f",
		"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff43", // max prime

#if MCL_MAX_BIT_SIZE >= 384
		// N = 6
		"0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff",
#endif

#if MCL_MAX_BIT_SIZE >= 521
		// N = 9
		"0x1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
#endif
	};
	for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) {
		printf("prime=%s\n", tbl[i]);
		test.run(tbl[i]);
	}
}
<|endoftext|>


<commit_before>#include "delegate/Glue.hxx"
#include "delegate/Handler.hxx"
#include "delegate/Stock.hxx"
#include "spawn/Config.hxx"
#include "spawn/ChildOptions.hxx"
#include "spawn/Registry.hxx"
#include "spawn/Local.hxx"
#include "stock/MapStock.hxx"
#include "async.hxx"
#include "event/Loop.hxx"
#include "event/DeferEvent.hxx"
#include "event/Callback.hxx"
#include "RootPool.hxx"
#include "pool.hxx"

#include <glib.h>

#include <assert.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>

static const char helper_path[] = "./cm4all-beng-proxy-delegate-helper";
static StockMap *delegate_stock;

class MyDelegateHandler final : public DelegateHandler {
    DeferEvent defer;

public:
    MyDelegateHandler()
        :defer(MakeSimpleEventCallback(MyDelegateHandler, Stop), this) {}

    void Stop() {
        delete delegate_stock;
    }

    void OnDelegateSuccess(int fd) override {
        close(fd);

        defer.Add();
    }

    void OnDelegateError(GError *error) override {
        g_printerr("%s\n", error->message);
        g_error_free(error);

        defer.Add();
    }
};

int main(int argc, char **argv)
{
    struct async_operation_ref my_async_ref;

    if (argc != 2) {
        fprintf(stderr, "usage: run-delegate PATH\n");
        return 1;
    }

    SpawnConfig spawn_config;

    EventLoop event_loop;

    ChildProcessRegistry child_process_registry(event_loop);
    child_process_registry.SetVolatile();

    LocalSpawnService spawn_service(spawn_config, child_process_registry);

    RootPool root_pool;
    delegate_stock = delegate_stock_new(spawn_service);
    LinearPool pool(root_pool, "test", 8192);

    ChildOptions child_options;

    MyDelegateHandler handler;
    delegate_stock_open(delegate_stock, pool, helper_path, child_options,
                        argv[1],
                        handler, my_async_ref);

    event_loop.Dispatch();
}
<commit_msg>test/run_delegate: use LightDeferEvent instead of DeferEvent<commit_after>#include "delegate/Glue.hxx"
#include "delegate/Handler.hxx"
#include "delegate/Stock.hxx"
#include "spawn/Config.hxx"
#include "spawn/ChildOptions.hxx"
#include "spawn/Registry.hxx"
#include "spawn/Local.hxx"
#include "stock/MapStock.hxx"
#include "async.hxx"
#include "event/Loop.hxx"
#include "event/LightDeferEvent.hxx"
#include "RootPool.hxx"
#include "pool.hxx"

#include <glib.h>

#include <assert.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>

static const char helper_path[] = "./cm4all-beng-proxy-delegate-helper";
static StockMap *delegate_stock;

class MyDelegateHandler final : public DelegateHandler, LightDeferEvent {
public:
    MyDelegateHandler(EventLoop &event_loop)
        :LightDeferEvent(event_loop) {}

    void Stop() {
        delete delegate_stock;
    }

    void OnDelegateSuccess(int fd) override {
        close(fd);

        LightDeferEvent::Schedule();
    }

    void OnDelegateError(GError *error) override {
        g_printerr("%s\n", error->message);
        g_error_free(error);

        LightDeferEvent::Schedule();
    }

private:
    /* virtual methods from class LightDeferEvent */
    void OnDeferred() override {
        Stop();
    }
};

int main(int argc, char **argv)
{
    struct async_operation_ref my_async_ref;

    if (argc != 2) {
        fprintf(stderr, "usage: run-delegate PATH\n");
        return 1;
    }

    SpawnConfig spawn_config;

    EventLoop event_loop;

    ChildProcessRegistry child_process_registry(event_loop);
    child_process_registry.SetVolatile();

    LocalSpawnService spawn_service(spawn_config, child_process_registry);

    RootPool root_pool;
    delegate_stock = delegate_stock_new(spawn_service);
    LinearPool pool(root_pool, "test", 8192);

    ChildOptions child_options;

    MyDelegateHandler handler(event_loop);
    delegate_stock_open(delegate_stock, pool, helper_path, child_options,
                        argv[1],
                        handler, my_async_ref);

    event_loop.Dispatch();
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: imapinfo.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: pjunck $ $Date: 2004-11-03 08:51:43 $
 *
 *  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 _SD_IMAPINFO_HXX
#define _SD_IMAPINFO_HXX

#ifndef _SD_SDIOCMPT_HXX
#include "sdiocmpt.hxx"
#endif
#ifndef _SD_GLOB_HXX
#include "glob.hxx"
#endif
#ifndef _SVDOBJ_HXX //autogen
#include <svx/svdobj.hxx>
#endif
#ifndef _IMAP_HXX //autogen
#include <svtools/imap.hxx>
#endif

/*************************************************************************
|*
|*
|*
\************************************************************************/

class SdIMapInfo : public SdrObjUserData, public SfxListener
{

    ImageMap        aImageMap;

public:
                    SdIMapInfo() :
                        SdrObjUserData( SdUDInventor, SD_IMAPINFO_ID, 0 ) {};

                    SdIMapInfo( const ImageMap& rImageMap ) :
                        SdrObjUserData( SdUDInventor, SD_IMAPINFO_ID, 0 ),
                        aImageMap( rImageMap ) {};

                    SdIMapInfo( const SdIMapInfo& rIMapInfo ) :
                        SdrObjUserData( SdUDInventor, SD_IMAPINFO_ID, 0 ),
                        aImageMap( rIMapInfo.aImageMap ) {};

    virtual         ~SdIMapInfo() {};

    virtual SdrObjUserData* Clone( SdrObject* pObj ) const { return new SdIMapInfo( *this ); }

//BFS02 virtual void WriteData( SvStream& rOStm );
//BFS02 virtual void ReadData( SvStream& rIStm );

    void            SetImageMap( const ImageMap& rIMap ) { aImageMap = rIMap; }
    const ImageMap& GetImageMap() const { return aImageMap; }
};

/*************************************************************************
|*
|*
|*
\************************************************************************/

//BFS02inline void SdIMapInfo::WriteData( SvStream& rOStm )
//BFS02{
//BFS02 SdrObjUserData::WriteData( rOStm );
//BFS02
//BFS02 SdIOCompat aIO( rOStm, STREAM_WRITE, 1 );
//BFS02
//BFS02 rOStm << aImageMap;
//BFS02}

/*************************************************************************
|*
|*
|*
\************************************************************************/

//BFS02inline void SdIMapInfo::ReadData( SvStream& rIStm )
//BFS02{
//BFS02 SdrObjUserData::ReadData( rIStm );
//BFS02
//BFS02 SdIOCompat aIO( rIStm, STREAM_READ );
//BFS02
//BFS02 rIStm >> aImageMap;
//BFS02}

#endif      // _SD_IMAPINFO_HXX

<commit_msg>INTEGRATION: CWS sb19 (1.1.1.1.612); FILE MERGED 2004/12/08 11:18:41 sb 1.1.1.1.612.2: RESYNC: (1.1.1.1-1.2); FILE MERGED 2004/10/27 07:32:09 mba 1.1.1.1.612.1: #110407#: remove static BaseURL<commit_after>/*************************************************************************
 *
 *  $RCSfile: imapinfo.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2005-01-11 12:08:54 $
 *
 *  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 _SD_IMAPINFO_HXX
#define _SD_IMAPINFO_HXX

#ifndef _SD_SDIOCMPT_HXX
#include "sdiocmpt.hxx"
#endif
#ifndef _SD_GLOB_HXX
#include "glob.hxx"
#endif
#ifndef _SVDOBJ_HXX //autogen
#include <svx/svdobj.hxx>
#endif
#ifndef _IMAP_HXX //autogen
#include <svtools/imap.hxx>
#endif

/*************************************************************************
|*
|*
|*
\************************************************************************/

class SdIMapInfo : public SdrObjUserData, public SfxListener
{

    ImageMap        aImageMap;

public:
                    SdIMapInfo() :
                        SdrObjUserData( SdUDInventor, SD_IMAPINFO_ID, 0 ) {};

                    SdIMapInfo( const ImageMap& rImageMap ) :
                        SdrObjUserData( SdUDInventor, SD_IMAPINFO_ID, 0 ),
                        aImageMap( rImageMap ) {};

                    SdIMapInfo( const SdIMapInfo& rIMapInfo ) :
                        SdrObjUserData( SdUDInventor, SD_IMAPINFO_ID, 0 ),
                        aImageMap( rIMapInfo.aImageMap ) {};

    virtual         ~SdIMapInfo() {};

    virtual SdrObjUserData* Clone( SdrObject* pObj ) const { return new SdIMapInfo( *this ); }

    void            SetImageMap( const ImageMap& rIMap ) { aImageMap = rIMap; }
    const ImageMap& GetImageMap() const { return aImageMap; }
};

#endif      // _SD_IMAPINFO_HXX

<|endoftext|>


<commit_before>#include "include/dvqmlcommunication.hpp"
#include <QWindow>

DVQmlCommunication::DVQmlCommunication(QWindow* parent) : QObject(parent), m_mirrorLeft(false),
    m_mirrorRight(false), m_greyFac(0.0), m_drawMode(Anglaph), m_anamorphicDualView(false), owner(parent) {
    connect(owner, &QWindow::windowStateChanged, this, &DVQmlCommunication::ownerWindowStateChanged);
}

bool DVQmlCommunication::isLeft() const {
    return m_isLeft;
}

DVQmlCommunication::DrawMode DVQmlCommunication::drawMode() const {
    return m_drawMode;
}

void DVQmlCommunication::setDrawMode(DrawMode mode) {
    /* Only emit if changed. */
    if(m_drawMode != mode) {
        m_drawMode = mode;
        emit drawModeChanged(mode);
    }
}

bool DVQmlCommunication::anamorphicDualView() const {
    return m_anamorphicDualView;
}

void DVQmlCommunication::setAnamorphicDualView(bool anamorphic) {
    /* Only emit if changed. */
    if(m_anamorphicDualView != anamorphic) {
        m_anamorphicDualView = anamorphic;
        emit anamorphicDualViewChanged(anamorphic);
    }
}

bool DVQmlCommunication::mirrorLeft() const {
    return m_mirrorLeft;
}

void DVQmlCommunication::setMirrorLeft(bool mirror) {
    /* Only emit if changed. */
    if (m_mirrorLeft != mirror) {
        m_mirrorLeft = mirror;
        emit mirrorLeftChanged(mirror);
    }
}

bool DVQmlCommunication::mirrorRight() const {
    return m_mirrorRight;
}

void DVQmlCommunication::setMirrorRight(bool mirror) {
    /* Only emit if changed. */
    if (m_mirrorRight != mirror) {
        m_mirrorRight = mirror;
        emit mirrorRightChanged(mirror);
    }
}

bool DVQmlCommunication::fullscreen() const {
    return owner->windowState() == Qt::WindowFullScreen;
}

void DVQmlCommunication::setFullscreen(bool fullscreen) {
    /* Only set if changed. */
    if (fullscreen != (owner->windowState() == Qt::WindowFullScreen))
        owner->setWindowState(fullscreen ? Qt::WindowFullScreen : Qt::WindowMaximized);

    /* Signal will be emitted because of the state change. */
}

void DVQmlCommunication::ownerWindowStateChanged(Qt::WindowState windowState) {
    emit fullscreenChanged(windowState == Qt::WindowFullScreen);
}

qreal DVQmlCommunication::greyFac() {
    return m_greyFac;
}

void DVQmlCommunication::setGreyFac(qreal fac) {
    /* Limit to [0, 1] range. */
    fac = qBound(0.0, fac, 1.0);

    /* Only emit if changed. */
    if (fac != m_greyFac) {
        m_greyFac = fac;
        emit greyFacChanged(fac);
    }
}
<commit_msg>Missed line in last commit.<commit_after>#include "include/dvqmlcommunication.hpp"
#include <QWindow>

DVQmlCommunication::DVQmlCommunication(QWindow* parent) : QObject(parent), m_mirrorLeft(false),
    m_mirrorRight(false), m_greyFac(0.0), m_drawMode(Anglaph), m_anamorphicDualView(false), owner(parent) {
    connect(owner, &QWindow::windowStateChanged, this, &DVQmlCommunication::ownerWindowStateChanged);
}

bool DVQmlCommunication::isLeft() const {
    return m_isLeft;
}

DVQmlCommunication::DrawMode DVQmlCommunication::drawMode() const {
    return m_drawMode;
}

void DVQmlCommunication::setDrawMode(DrawMode mode) {
    /* Only emit if changed. */
    if(m_drawMode != mode) {
        m_drawMode = mode;
        emit drawModeChanged(mode);
    }
}

bool DVQmlCommunication::anamorphicDualView() const {
    return m_anamorphicDualView;
}

void DVQmlCommunication::setAnamorphicDualView(bool anamorphic) {
    /* Only emit if changed. */
    if(m_anamorphicDualView != anamorphic) {
        m_anamorphicDualView = anamorphic;
        emit anamorphicDualViewChanged(anamorphic);
    }
}

bool DVQmlCommunication::mirrorLeft() const {
    return m_mirrorLeft;
}

void DVQmlCommunication::setMirrorLeft(bool mirror) {
    /* Only emit if changed. */
    if (m_mirrorLeft != mirror) {
        m_mirrorLeft = mirror;
        emit mirrorLeftChanged(mirror);
    }
}

bool DVQmlCommunication::mirrorRight() const {
    return m_mirrorRight;
}

void DVQmlCommunication::setMirrorRight(bool mirror) {
    /* Only emit if changed. */
    if (m_mirrorRight != mirror) {
        m_mirrorRight = mirror;
        emit mirrorRightChanged(mirror);
    }
}

bool DVQmlCommunication::fullscreen() const {
    return owner->windowState() == Qt::WindowFullScreen;
}

void DVQmlCommunication::setFullscreen(bool fullscreen) {
    /* Only set if changed. */
    if (fullscreen != (owner->windowState() == Qt::WindowFullScreen))
        owner->setWindowState(fullscreen ? Qt::WindowFullScreen : Qt::WindowMaximized);

    /* Signal will be emitted because of the state change. */
}

void DVQmlCommunication::ownerWindowStateChanged(Qt::WindowState windowState) {
    emit fullscreenChanged(windowState == Qt::WindowFullScreen);
}

qreal DVQmlCommunication::greyFac() const {
    return m_greyFac;
}

void DVQmlCommunication::setGreyFac(qreal fac) {
    /* Limit to [0, 1] range. */
    fac = qBound(0.0, fac, 1.0);

    /* Only emit if changed. */
    if (fac != m_greyFac) {
        m_greyFac = fac;
        emit greyFacChanged(fac);
    }
}
<|endoftext|>


<commit_before>/*
 */
#include <synext_macro.hpp>
#include "../parse/common.hpp"
#include "../parse/parseerror.hpp"
#include "../parse/tokentree.hpp"
#include "../parse/lex.hpp"

namespace {

    struct FmtArgs
    {
        enum class Align {
            Unspec,
            Left,
            Center,
            Right,
        };
        enum class Sign {
            Unspec,
            Plus,
            Minus,
        };

        Align   align = Align::Unspec;
        char    align_char = ' ';

        Sign    sign = Sign::Unspec;
        bool    alternate = false;
        bool    zero_pad = false;

        bool width_is_arg = false;
        unsigned int width = 0;

        bool prec_is_arg = false;
        unsigned int prec = 0;
    };

    struct FmtFrag
    {
        ::std::string   leading_text;

        unsigned int    arg_index;

        const char* trait_name;
        // TODO: Support case where this hasn't been edited (telling the formatter that it has nothing to apply)
        FmtArgs     args;
    };

    ::std::tuple< ::std::vector<FmtFrag>, ::std::string> parse_format_string(const Span& sp, const ::std::string& format_string, const ::std::map< ::std::string,unsigned int>& named, unsigned int n_free)
    {
        unsigned int n_named = named.size();
        unsigned int next_free = 0;

        ::std::vector<FmtFrag>  frags;
        ::std::string   cur_literal;

        const char* s = format_string.c_str();
        for( ; *s; s ++)
        {
            if( *s != '{' )
            {
                if( *s == '}' ) {
                    s ++;
                    if( *s != '}' )
                        ERROR(sp, E0000, "'}' must be escaped as '}}' in format strings");
                    // - fall with *s == '}'
                }
                cur_literal += *s;
            }
            else
            {
                s ++;
                if( *s == '{' ) {
                    cur_literal += '{';
                    continue ;
                }

                unsigned int index = ~0u;
                const char* trait_name;
                FmtArgs args;

                // Formatting parameter
                if( *s != ':' && *s != '}' ) {
                    // Parse either an integer or an identifer
                    TODO(sp, "Parse named/positional formatting fragment at \"" << s);
                }
                else {
                    // Leave (for now)
                    // - If index is ~0u at the end of this block, it's set to the next arg
                    // - This allows {:.*} to format correctly (taking <prec> then <arg>)
                }

                // If next character is ':', parse extra information
                if( *s == ':' ) {
                    s ++;   // eat ':'

                    // Alignment
                    if( s[0] != '\0' && (s[1] == '<' || s[1] == '^' || s[1] == '>') ) {
                        args.align_char = s[0];
                        s ++;
                    }
                    if( *s == '<' ) {
                        args.align = FmtArgs::Align::Left;
                        s ++;
                    }
                    else if( *s == '^' ) {
                        args.align = FmtArgs::Align::Center;
                        s ++;
                    }
                    else if( *s == '>' ) {
                        args.align = FmtArgs::Align::Right;
                        s ++;
                    }
                    else {
                        //args.align = FmtArgs::Align::Unspec;
                    }

                    // Sign
                    if( *s == '+' ) {
                        args.sign = FmtArgs::Sign::Plus;
                        s ++;
                    }
                    else if( *s == '-' ) {
                        args.sign = FmtArgs::Sign::Minus;
                        s ++;
                    }
                    else {
                        args.sign = FmtArgs::Sign::Unspec;
                    }

                    if( *s == '#' ) {
                        args.alternate = true;
                        s ++;
                    }
                    else {
                        //args.alternate = false;
                    }

                    if( *s == '0' ) {
                        args.zero_pad = true;
                        s ++;
                    }
                    else {
                        //args.zero_pad = false;
                    }

                    // Padded width
                    if( ::std::isdigit(*s) /*|| *s == '*'*/ ) {
                        unsigned int val = 0;
                        while( ::std::isdigit(*s) )
                        {
                            val *= 10;
                            val += *s - '0';
                            s ++;
                        }
                        args.width = val;

                        if( *s == '$' ) {
                            args.width_is_arg = true;
                            s ++;
                        }
                        else {
                            //args.width_is_arg = false;
                        }
                    }
                    // Precision
                    if( *s == '.' ) {
                        s ++;
                        // '*' - Use next argument
                        if( *s == '*' ) {
                            args.prec_is_arg = true;
                            if( next_free == n_free ) {
                                ERROR(sp, E0000, "Not enough arguments passed, expected at least " << n_free+1);
                            }
                            args.prec = next_free + n_named;
                            next_free ++;
                        }
                        else {
                            unsigned int val = 0;
                            while( ::std::isdigit(*s) )
                            {
                                val *= 10;
                                val += *s - '0';
                                s ++;
                            }
                            args.prec = val;

                            if( *s == '$' ) {
                                args.prec_is_arg = true;
                                s ++;
                            }
                            else {
                                //args.prec_is_arg = false;
                            }
                        }
                    }

                    // Parse ident?
                    // - Lazy way is to just handle a single char and ensure that it is just a single char
                    if( s[0] != '}' && s[0] != '\0' && s[1] != '}' ) {
                        TODO(sp, "Parse formatting fragment at \"" << s << "\" (long type)");
                    }

                    switch(s[0])
                    {
                    case '\0':
                        ERROR(sp, E0000, "Unexpected end of formatting string");
                    default:
                        ERROR(sp, E0000, "Unknown formatting type specifier '" << *s << "'");
                    case '}':      trait_name = "Display"; break;
                    case '?': s++; trait_name = "Debug"  ; break;
                    case 'b': s++; trait_name = "Binary"; break;
                    case 'o': s++; trait_name = "Octal" ; break;
                    case 'x': s++; trait_name = "LowerHex"; break;
                    case 'X': s++; trait_name = "UpperHex"; break;
                    case 'p': s++; trait_name = "Pointer" ; break;
                    case 'e': s++; trait_name = "LowerExp"; break;
                    case 'E': s++; trait_name = "UpperExp"; break;
                    }
                    assert(*s == '}');
                }
                else {
                    if( *s != '}' )
                        ERROR(sp, E0000, "Malformed formatting fragment, unexpected " << *s);
                    // Otherwise, it's just a trivial Display call
                    trait_name = "Display";
                }

                // Set index if unspecified
                if( index == ~0u )
                {
                    if( next_free == n_free ) {
                        ERROR(sp, E0000, "Not enough arguments passed, expected at least " << n_free+1);
                    }
                    index = next_free + n_named;
                    next_free ++;
                }

                frags.push_back( FmtFrag {
                    mv$(cur_literal),
                    index, trait_name,
                    mv$(args)
                    });
            }
        }

        return ::std::make_tuple( mv$(frags), mv$(cur_literal) );
    }
}

class CFormatArgsExpander:
    public ExpandProcMacro
{
    bool    expand_early() const override { return true; }

    ::std::unique_ptr<TokenStream> expand(const Span& sp, const ::AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override
    {
        Token   tok;

        auto lex = TTStream(tt);
        if( ident != "" )
            ERROR(sp, E0000, "format_args! doesn't take an ident");

        auto n = Parse_ExprVal(lex);
        auto format_string = dynamic_cast<AST::ExprNode_String&>(*n).m_value;

        ::std::map< ::std::string, unsigned int>   named_args_index;
        ::std::vector<TokenTree>    named_args;
        ::std::vector<TokenTree>    free_args;

        // - Parse the arguments
        while( GET_TOK(tok, lex) == TOK_COMMA )
        {
            // - Named parameters
            if( lex.lookahead(0) == TOK_IDENT && lex.lookahead(1) == TOK_EQUAL )
            {
                GET_CHECK_TOK(tok, lex, TOK_IDENT);
                auto name = mv$(tok.str());

                GET_CHECK_TOK(tok, lex, TOK_EQUAL);

                auto expr_tt = Parse_TT_Expr(lex);

                auto ins_rv = named_args_index.insert( ::std::make_pair(mv$(name), named_args.size()) );
                if( ins_rv.second == false ) {
                    ERROR(sp, E0000, "Duplicate definition of named argument `" << ins_rv.first->first << "`");
                }
                named_args.push_back( mv$(expr_tt) );
            }
            // - Free parameters
            else
            {
                auto expr_tt = Parse_TT_Expr(lex);
                free_args.push_back( mv$(expr_tt) );
            }
        }

        // - Parse the format string
        ::std::vector< FmtFrag> fragments;
        ::std::string   tail;
        ::std::tie( fragments, tail ) = parse_format_string(sp, format_string,  named_args_index, free_args.size());

        // TODO: Properly expand format_args! (requires mangling to fit ::core::fmt::rt::v1)
        // - For now, just emits the text with no corresponding format fragments

        ::std::vector<TokenTree> toks;
        {
            // TODO: Figure out what path to use (::fmt, ::core::fmt, or ::std::fmt)

            //toks.push_back( TokenTree(TOK_DOUBLE_COLON) );
            //toks.push_back( Token(TOK_IDENT, "std") ); //toks.push_back( Token(TOK_STRING, "core") );
            toks.push_back( TokenTree(TOK_DOUBLE_COLON) );
            toks.push_back( Token(TOK_IDENT, "fmt") );
            toks.push_back( TokenTree(TOK_DOUBLE_COLON) );
            toks.push_back( Token(TOK_IDENT, "Arguments") );
            toks.push_back( TokenTree(TOK_DOUBLE_COLON) );
            toks.push_back( Token(TOK_IDENT, "new_v1") );
            toks.push_back( TokenTree(TOK_PAREN_OPEN) );
            {
                toks.push_back( TokenTree(TOK_AMP) );
                toks.push_back( TokenTree(TOK_SQUARE_OPEN) );
                for(const auto& frag : fragments ) {
                    toks.push_back( Token(TOK_STRING, frag.leading_text) );
                    toks.push_back( TokenTree(TOK_COMMA) );
                }
                toks.push_back( TokenTree(TOK_SQUARE_CLOSE) );
                toks.push_back( TokenTree(TOK_COMMA) );

                toks.push_back( TokenTree(TOK_AMP) );
                toks.push_back( TokenTree(TOK_SQUARE_OPEN) );
                toks.push_back( TokenTree(TOK_SQUARE_CLOSE) );
            }
            toks.push_back( TokenTree(TOK_PAREN_CLOSE) );
        }

        return box$( TTStreamO(TokenTree(mv$(toks))) );
    }
};

STATIC_MACRO("format_args", CFormatArgsExpander);

<commit_msg>Expand format_args - Add detection for ::std/::core<commit_after>/*
 */
#include <synext_macro.hpp>
#include "../parse/common.hpp"
#include "../parse/parseerror.hpp"
#include "../parse/tokentree.hpp"
#include "../parse/lex.hpp"
#include <ast/crate.hpp>    // for m_load_std

namespace {

    struct FmtArgs
    {
        enum class Align {
            Unspec,
            Left,
            Center,
            Right,
        };
        enum class Sign {
            Unspec,
            Plus,
            Minus,
        };

        Align   align = Align::Unspec;
        char    align_char = ' ';

        Sign    sign = Sign::Unspec;
        bool    alternate = false;
        bool    zero_pad = false;

        bool width_is_arg = false;
        unsigned int width = 0;

        bool prec_is_arg = false;
        unsigned int prec = 0;
    };

    struct FmtFrag
    {
        ::std::string   leading_text;

        unsigned int    arg_index;

        const char* trait_name;
        // TODO: Support case where this hasn't been edited (telling the formatter that it has nothing to apply)
        FmtArgs     args;
    };

    ::std::tuple< ::std::vector<FmtFrag>, ::std::string> parse_format_string(const Span& sp, const ::std::string& format_string, const ::std::map< ::std::string,unsigned int>& named, unsigned int n_free)
    {
        unsigned int n_named = named.size();
        unsigned int next_free = 0;

        ::std::vector<FmtFrag>  frags;
        ::std::string   cur_literal;

        const char* s = format_string.c_str();
        for( ; *s; s ++)
        {
            if( *s != '{' )
            {
                if( *s == '}' ) {
                    s ++;
                    if( *s != '}' )
                        ERROR(sp, E0000, "'}' must be escaped as '}}' in format strings");
                    // - fall with *s == '}'
                }
                cur_literal += *s;
            }
            else
            {
                s ++;
                if( *s == '{' ) {
                    cur_literal += '{';
                    continue ;
                }

                unsigned int index = ~0u;
                const char* trait_name;
                FmtArgs args;

                // Formatting parameter
                if( *s != ':' && *s != '}' ) {
                    // Parse either an integer or an identifer
                    TODO(sp, "Parse named/positional formatting fragment at \"" << s);
                }
                else {
                    // Leave (for now)
                    // - If index is ~0u at the end of this block, it's set to the next arg
                    // - This allows {:.*} to format correctly (taking <prec> then <arg>)
                }

                // If next character is ':', parse extra information
                if( *s == ':' ) {
                    s ++;   // eat ':'

                    // Alignment
                    if( s[0] != '\0' && (s[1] == '<' || s[1] == '^' || s[1] == '>') ) {
                        args.align_char = s[0];
                        s ++;
                    }
                    if( *s == '<' ) {
                        args.align = FmtArgs::Align::Left;
                        s ++;
                    }
                    else if( *s == '^' ) {
                        args.align = FmtArgs::Align::Center;
                        s ++;
                    }
                    else if( *s == '>' ) {
                        args.align = FmtArgs::Align::Right;
                        s ++;
                    }
                    else {
                        //args.align = FmtArgs::Align::Unspec;
                    }

                    // Sign
                    if( *s == '+' ) {
                        args.sign = FmtArgs::Sign::Plus;
                        s ++;
                    }
                    else if( *s == '-' ) {
                        args.sign = FmtArgs::Sign::Minus;
                        s ++;
                    }
                    else {
                        args.sign = FmtArgs::Sign::Unspec;
                    }

                    if( *s == '#' ) {
                        args.alternate = true;
                        s ++;
                    }
                    else {
                        //args.alternate = false;
                    }

                    if( *s == '0' ) {
                        args.zero_pad = true;
                        s ++;
                    }
                    else {
                        //args.zero_pad = false;
                    }

                    // Padded width
                    if( ::std::isdigit(*s) /*|| *s == '*'*/ ) {
                        unsigned int val = 0;
                        while( ::std::isdigit(*s) )
                        {
                            val *= 10;
                            val += *s - '0';
                            s ++;
                        }
                        args.width = val;

                        if( *s == '$' ) {
                            args.width_is_arg = true;
                            s ++;
                        }
                        else {
                            //args.width_is_arg = false;
                        }
                    }
                    // Precision
                    if( *s == '.' ) {
                        s ++;
                        // '*' - Use next argument
                        if( *s == '*' ) {
                            args.prec_is_arg = true;
                            if( next_free == n_free ) {
                                ERROR(sp, E0000, "Not enough arguments passed, expected at least " << n_free+1);
                            }
                            args.prec = next_free + n_named;
                            next_free ++;
                        }
                        else {
                            unsigned int val = 0;
                            while( ::std::isdigit(*s) )
                            {
                                val *= 10;
                                val += *s - '0';
                                s ++;
                            }
                            args.prec = val;

                            if( *s == '$' ) {
                                args.prec_is_arg = true;
                                s ++;
                            }
                            else {
                                //args.prec_is_arg = false;
                            }
                        }
                    }

                    // Parse ident?
                    // - Lazy way is to just handle a single char and ensure that it is just a single char
                    if( s[0] != '}' && s[0] != '\0' && s[1] != '}' ) {
                        TODO(sp, "Parse formatting fragment at \"" << s << "\" (long type)");
                    }

                    switch(s[0])
                    {
                    case '\0':
                        ERROR(sp, E0000, "Unexpected end of formatting string");
                    default:
                        ERROR(sp, E0000, "Unknown formatting type specifier '" << *s << "'");
                    case '}':      trait_name = "Display"; break;
                    case '?': s++; trait_name = "Debug"  ; break;
                    case 'b': s++; trait_name = "Binary"; break;
                    case 'o': s++; trait_name = "Octal" ; break;
                    case 'x': s++; trait_name = "LowerHex"; break;
                    case 'X': s++; trait_name = "UpperHex"; break;
                    case 'p': s++; trait_name = "Pointer" ; break;
                    case 'e': s++; trait_name = "LowerExp"; break;
                    case 'E': s++; trait_name = "UpperExp"; break;
                    }
                    assert(*s == '}');
                }
                else {
                    if( *s != '}' )
                        ERROR(sp, E0000, "Malformed formatting fragment, unexpected " << *s);
                    // Otherwise, it's just a trivial Display call
                    trait_name = "Display";
                }

                // Set index if unspecified
                if( index == ~0u )
                {
                    if( next_free == n_free ) {
                        ERROR(sp, E0000, "Not enough arguments passed, expected at least " << n_free+1);
                    }
                    index = next_free + n_named;
                    next_free ++;
                }

                frags.push_back( FmtFrag {
                    mv$(cur_literal),
                    index, trait_name,
                    mv$(args)
                    });
            }
        }

        return ::std::make_tuple( mv$(frags), mv$(cur_literal) );
    }
}

class CFormatArgsExpander:
    public ExpandProcMacro
{
    bool    expand_early() const override { return true; }

    ::std::unique_ptr<TokenStream> expand(const Span& sp, const ::AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override
    {
        Token   tok;

        auto lex = TTStream(tt);
        if( ident != "" )
            ERROR(sp, E0000, "format_args! doesn't take an ident");

        auto n = Parse_ExprVal(lex);
        auto format_string = dynamic_cast<AST::ExprNode_String&>(*n).m_value;

        ::std::map< ::std::string, unsigned int>   named_args_index;
        ::std::vector<TokenTree>    named_args;
        ::std::vector<TokenTree>    free_args;

        // - Parse the arguments
        while( GET_TOK(tok, lex) == TOK_COMMA )
        {
            // - Named parameters
            if( lex.lookahead(0) == TOK_IDENT && lex.lookahead(1) == TOK_EQUAL )
            {
                GET_CHECK_TOK(tok, lex, TOK_IDENT);
                auto name = mv$(tok.str());

                GET_CHECK_TOK(tok, lex, TOK_EQUAL);

                auto expr_tt = Parse_TT_Expr(lex);

                auto ins_rv = named_args_index.insert( ::std::make_pair(mv$(name), named_args.size()) );
                if( ins_rv.second == false ) {
                    ERROR(sp, E0000, "Duplicate definition of named argument `" << ins_rv.first->first << "`");
                }
                named_args.push_back( mv$(expr_tt) );
            }
            // - Free parameters
            else
            {
                auto expr_tt = Parse_TT_Expr(lex);
                free_args.push_back( mv$(expr_tt) );
            }
        }

        // - Parse the format string
        ::std::vector< FmtFrag> fragments;
        ::std::string   tail;
        ::std::tie( fragments, tail ) = parse_format_string(sp, format_string,  named_args_index, free_args.size());

        // TODO: Properly expand format_args! (requires mangling to fit ::core::fmt::rt::v1)
        // - For now, just emits the text with no corresponding format fragments

        ::std::vector<TokenTree> toks;
        {
            // TODO: Figure out what path to use (::fmt, ::core::fmt, or ::std::fmt)

            switch(crate.m_load_std)
            {
            case ::AST::Crate::LOAD_NONE:
                break;
            case ::AST::Crate::LOAD_CORE:
                toks.push_back( TokenTree(TOK_DOUBLE_COLON) );
                toks.push_back( Token(TOK_STRING, "core") );
                break;
            case ::AST::Crate::LOAD_STD:
                toks.push_back( TokenTree(TOK_DOUBLE_COLON) );
                toks.push_back( Token(TOK_IDENT, "std") );
                break;
            }
            toks.push_back( TokenTree(TOK_DOUBLE_COLON) );
            toks.push_back( Token(TOK_IDENT, "fmt") );
            toks.push_back( TokenTree(TOK_DOUBLE_COLON) );
            toks.push_back( Token(TOK_IDENT, "Arguments") );
            toks.push_back( TokenTree(TOK_DOUBLE_COLON) );
            toks.push_back( Token(TOK_IDENT, "new_v1") );
            toks.push_back( TokenTree(TOK_PAREN_OPEN) );
            {
                toks.push_back( TokenTree(TOK_AMP) );
                toks.push_back( TokenTree(TOK_SQUARE_OPEN) );
                for(const auto& frag : fragments ) {
                    toks.push_back( Token(TOK_STRING, frag.leading_text) );
                    toks.push_back( TokenTree(TOK_COMMA) );
                }
                toks.push_back( TokenTree(TOK_SQUARE_CLOSE) );
                toks.push_back( TokenTree(TOK_COMMA) );

                toks.push_back( TokenTree(TOK_AMP) );
                toks.push_back( TokenTree(TOK_SQUARE_OPEN) );
                toks.push_back( TokenTree(TOK_SQUARE_CLOSE) );
            }
            toks.push_back( TokenTree(TOK_PAREN_CLOSE) );
        }

        return box$( TTStreamO(TokenTree(mv$(toks))) );
    }
};

STATIC_MACRO("format_args", CFormatArgsExpander);

<|endoftext|>