Commit 96c4f6a0 authored by Antonino's avatar Antonino

First Commit

parents
File input_parser.cpp
Copyright (C) 2025 D'Anna Antonino
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
================================================================================
input_parser.cpp parses input fule meant for mesons.c and tm_mesons.c in their
latest version available on Jul 2025. To run it, type
input_parser.x <input_file1.in> ...
It can take multiple input file at once and it will process them in sequence.
It generate two files:
<input_file>_corr.txt: contains the complete list of all the correlators included
in the input file. For each correlator it will specify the
type (2pt, 3pt,...), the propagators involved in the contraction,
the gamma structures and their position, source, sink and
injection position and will specify, if possible, the moving
position.
<input_file>_condense_corr.txt: contains the complete list of correlators in the
input file with unique propagators contents.
I.e: if two correlator differs only in the gamma
structures, only one is kept while the other is
discarded. It will print the same informations
as above
Options:
[-o <output_dir>]: by default, the output file are saved in the same directory
of the input files. If the option [-o] is given, then the
output files will be saved in the <output_dir>.
#ifndef GAMMA_H_
#define GAMMA_H_
#include <string>
enum Gamma{
gamma0, gamma1, gamma2, gamma3,id, gamma5=5,
gamma01, gamma02, gamma03,gamma05=10,
gamma12=12, gamma13, gamma15=15,
gamma23=23, gamma25=25,
gamma35=35,
};
// Takes a string 'g' and return the associated Gamma::gamma_matrix element
inline Gamma stog(std::string g){
// std::cout << g << std::endl;
if(g.length()==0){
std::cerr<< "[stog] Empty string" << std::endl;
exit(0);
}
if(g.length() ==1){
if(g!="1"){
std::cerr << "[stog] invalid gamma structure " << g << std::endl;
exit(1);
}
return Gamma::id;
}
if(g.length()==2) return static_cast<Gamma>(g[1]-'0');
if ( g.length()==3 || g.length()>=5){
std::cerr << "[stog] invalid gamma structure " << g << std::endl;
exit(1);
}
int a = g[1]-'0';
int b = g[3]-'0';
if (a==0) return static_cast<Gamma>(5+ b);
return static_cast<Gamma>(a*10+b);
}
// Takes a Gamma::gamma_matrix and return the associated std::string
inline std::string gtos(Gamma g){
switch(g){
case gamma0: return "G0";
case gamma1: return "G1";
case gamma2: return "G2";
case gamma3: return "G3";
case id: return "1";
case gamma5: return "G5";
case gamma01: return "G0G1";
case gamma02: return "G0G2";
case gamma03: return "G0G3";
case gamma05: return "G0G5";
case gamma12: return "G1G2";
case gamma13: return "G1G3";
case gamma15: return "G1G5";
case gamma23: return "G2G3";
case gamma25: return "G2G5";
case gamma35: return "G3G5";
default:
std::cerr << "[gtos] gamma structure " << g<<" not defined"<< std::endl;
exit(1);
}
}
#endif // GAMMA_H_
#ifndef CORRELATOR_H_
#define CORRELATOR_H_
#include <iostream>
#include <memory>
#include <array>
#include <vector>
#include "propagator.h"
#include "Gamma.h"
// corr Base virtual stcture for the correlators. It should never be used directly.
// Always refer to corr_npt<N>
struct corr{
virtual void print(std::ostream&)=0;
virtual size_t npoint() const = 0;
virtual int get_propagator_id(int i) const =0;
virtual ~corr()= default;
#if __cplusplus>=201402L
virtual std::unique_ptr<corr> make_unique_ptr() = 0;
#endif
};
template <size_t N>
struct corr_npt : corr {
std::array<int,N> propagator_id;
std::array<Gamma,N> gamma;
std::array<double,N> kappa;
std::array<double,N> mus;
std::array<int,N-1> xn;// position of the N points.
std::array<std::array<double,3>,N> theta;
std::array<bool,N> is_seq;
std::array<int,N> seq_id;
~corr_npt() override = default;
corr_npt(std::array<int,N> prop, std::array<Gamma,N> g, std::array<double, N> kappa, std::array<double,N> mu, std::array<int, N-1> xn,std::array<std::array<double,3>,N> theta,std::array<bool,N> is_seq, std::array<int,N> seq_id) :
propagator_id(prop),gamma(g),kappa(kappa),mus(mu),xn(xn),theta(theta),is_seq(is_seq),seq_id(seq_id){};
corr_npt(const corr_npt<N> &corrs) = default;
size_t npoint() const override {return N;};
int get_propagator_id(int i) const override {return propagator_id[i];};
void print(std::ostream& os) override;
#if __cplusplus>=201402L
std::unique_ptr<corr> make_unique_ptr() override;
#endif
};
void read_all_corr(std::ifstream &file, std::vector<std::unique_ptr<corr>> & corrs, std::vector<propagator> &prop, int ncorr);
bool compare_corr(const corr&A, const corr&B);
#if __cplusplus>=201402L
bool compare_corr(const std::unique_ptr<corr> &A, const std::unique_ptr<corr> &B);
void condense_correlator(std::vector<std::unique_ptr<corr>> &corrs);
#else
corr *compare_corr(const corr* A, corr* B);
void condense_correlators(std::vector<corr*> &corrs);
#endif
#endif // CORRELATOR_H_
#ifndef FILE_MANIP_H_
#define FILE_MANIP_H_
#include <fstream>
#include <string>
#include <regex>
#include <vector>
void find_section(std::ifstream &file, const std::string &section_name);
void read_line(std::ifstream &file, std::string &line);
void check_line(const std::string &line, const std::string &name);
std::string get_match(const std::string &line, const std::regex &rgx);
std::vector<std::string> get_all_match(const std::string &line, const std::regex &rgx);
void read_measurements(std::ifstream &file, std::vector<int> &par);
#endif // FILE_MANIP_H_
#ifndef PROPAGATOR_H
#define PROPAGATOR_H
#include <vector>
#include <array>
#include <iostream>
#include "Gamma.h"
struct propagator{
double kappa;
double mu;
std::array<double,3> theta;
bool seq_prop=false;
int seq_id=-1;
int src{-1};
Gamma seq_type;
friend std::ostream& operator<<(std::ostream& os, const propagator &prop);
};
void read_all_propagator(std::ifstream &file, std::vector<propagator>& props, int nprop);
#endif // PROPAGATOR_H
#include <vector>
#include <string>
#include <array>
#include <memory>
#include <regex>
#include "../include/correlator.h"
#include "../include/propagator.h"
#include "../include/file_manip.h"
template <size_t N>
void corr_npt<N>::print(std::ostream& os) {
os << N <<"-point correlator:" << std::endl;
os << "Gamma structures is: " << gtos(gamma[0]) << " " << gtos(gamma[1]) << " ";
if
#if __cplusplus >=201703L
constexpr
#endif
(N>2){
os << gtos(gamma[2]);
}
os << std::endl;
os << "source at "<< xn[0] << std::endl;
if
#if __cplusplus >=201703L
constexpr
#endif
(N>2){
os << "sink at " << xn[1] <<std::endl;
}
os << "propagator specification: "<<std::endl;
for(size_t i=0; i<N;i++){
os << "propagator id: "<< propagator_id[i]<< std::endl;
if(is_seq[i])
os << "Is sequential propagator. Source propagator id: " << seq_id[i] << std::endl;
os << "\t kappa:" << kappa[i] <<std::endl;
os << "\t mu: " << mus[i] << std::endl;
os << "\t theta:";
for(auto t :theta[i]) os << t << " ";
os <<std::endl;
}
os << std::endl;
os << "Gamma structure at source:" << gtos(gamma[0])<< std::endl;
if
#if __cplusplus >=201703L
constexpr
#endif
(N>2)
{
for(size_t i=2; i<N; i++)
os << "Gamma structure injected at: " << xn[i-1] << " " << gtos(gamma[i]) << std::endl;
}
os << "Gamma structure at sink (i.e varying position): " << gtos(gamma[1]) << std::endl;
}
template<size_t N>
#if __cplusplus >=201402L
std::unique_ptr<corr> corr_npt<N>::make_unique_ptr(){
return std::make_unique<corr_npt<N>>(*this);
}
#endif
// read a correlator form the input file.
// Some assumption are made:
// - you are at the beginning of the correlator section.
// - the correlator section is organized as:
// prop
// mu
// theta
// seq_prop
// seq_type
// seq_x0
//
void read_all_corr(std::ifstream &file, std::vector<std::unique_ptr<corr>> &corrs,std::vector<propagator> &prop, int ncorr){
corrs.clear();
corrs.resize(ncorr);
int npoint;
std::array<int,3> prop_id;
std::array<Gamma,3> gamma;
std::array<double,3> kappa;
std::array<double,3> mus;
std::array<bool,3> is_seq;
std::array<int, 3> seq_id;
std::array<int,2> xn;// position of the N points.
std::array<std::array<double,3>,3> theta;
std::string temp;
std::regex rgx_int("\\s[+-]?[0-9]+");
std::regex rgx_gamma("((G[0-5]){1,2})|1");
std::vector<std::string> aux;
for(auto i=0; i<ncorr; i++){
find_section(file, "Correlator "+std::to_string(i));
npoint = 2;
read_line(file, temp);
check_line(temp,"prop");
aux = get_all_match(temp,rgx_int);
prop_id[0] = std::stoi(aux[0]);
prop_id[1] = std::stoi(aux[1]);
is_seq = {false,false,false};
if(prop[prop_id[0]].seq_prop){
is_seq[0] = true;
npoint++;
prop_id[2] = prop[prop_id[0]].seq_id;
seq_id[0] = prop_id[2];
xn[1] = prop[prop_id[0]].src;
gamma[2] = prop[prop_id[0]].seq_type;
}
if(prop[prop_id[1]].seq_prop){
is_seq[1] = true;
npoint++;
prop_id[2] = prop[prop_id[1]].seq_id;
seq_id[1] = prop_id[2];
xn[1] = prop[prop_id[1]].src;
gamma[2] = prop[prop_id[1]].seq_type;
}
read_line(file,temp);
check_line(temp,"isubprop");
read_line(file,temp);
check_line(temp,"type");
aux = get_all_match(temp,rgx_gamma);
gamma[0] = stog(aux[0]);
gamma[1] = stog(aux[1]);
read_line(file,temp);
check_line(temp,"gsmear");
read_line(file,temp);
check_line(temp,"qsmear");
read_line(file,temp);
check_line(temp, "x0");
xn[0] = std::stoi(get_match(temp,rgx_int)); //
//
kappa[0] = prop[prop_id[0]].kappa;
kappa[1] = prop[prop_id[1]].kappa;
mus[0] = prop[prop_id[0]].mu;
mus[1] = prop[prop_id[1]].mu;
theta[0] = prop[prop_id[0]].theta;
theta[1] = prop[prop_id[1]].theta;
if(npoint ==2){
#if __cplusplus>=201402L
corrs[i]=std::make_unique<corr_npt<2>>(
corr_npt<2>(
std::array<int,2>{prop_id[0],prop_id[1]},
std::array<Gamma,2>{gamma[0],gamma[1]},
std::array<double,2>{kappa[0],kappa[1]},
std::array<double,2>{mus[0],mus[1]},
std::array<int,1>{xn[0]},
std::array<std::array<double,3>,2>{theta[0],theta[1]},
std::array<bool,2>{false,false},
std::array<int,2>{0,0}
)
);
#else
corrs[i]= new corr_npt<2>(std::array<int,2>{prop_id[0],prop_id[1]},
std::array<Gamma,2>{gamma[0],gamma[1]},
std::array<double,2>{kappa[0],kappa[1]},
std::array<double,2>{mus[0],mus[1]},
std::array<int,1>{xn[0]},
std::array<std::array<double,3>,2>{theta[0],theta[1]},
std::array<bool,2>{false,false},
std::array<int,2>{0,0}
);
#endif
}
else if(npoint==3){
kappa[2] = prop[prop_id[2]].kappa;
mus[2] = prop[prop_id[2]].mu;
theta[2] = prop[prop_id[2]].theta;
#if __cplusplus>= 201402L
corrs[i] = std::make_unique<corr_npt<3>>(corr_npt<3>(prop_id,gamma,kappa,mus,xn,theta,is_seq,seq_id));
#else
corrs[i] = new corr_npt<3>(prop_id,gamma,kappa,mus,xn,theta,is_seq,seq_id);
#endif
}
else if(npoint >3){
std::cerr << "[read_corr] "<< npoint <<"-point function are not supported yet. "<<std::endl;
std::cerr << "\t reading correlator " << i << "with propagators " << prop_id[0] << " " << prop_id[1] << std::endl;
exit(1);
}
}
}
bool compare_corr(const corr& A, const corr& B){
if (A.npoint()!=B.npoint()) return false;
for(size_t i =0;i<A.npoint() ; i++){
if(A.get_propagator_id(i) != B.get_propagator_id(i))
return false;
};
return true;
}
#if __cplusplus>=201402L
bool compare_corr(const std::unique_ptr<corr> &A, const std::unique_ptr<corr> &B){
return compare_corr(*A,*B);
}
#else
bool compare_corr(const corr* A, const corr *B){
if (A->npoint()!=B->npoint()) return false;
for(size_t i =0;i < A->npoint() ; i++){
if(A->get_propagator_id(i) != B->get_propagator_id(i))
return false;
};
return true;
}
#endif
#if __cplusplus>=201402L
void condense_correlator(std::vector<std::unique_ptr<corr>>& corrs){
std::vector<std::unique_ptr<corr>> condensed;
#else
void condense_correlator(std::vector<corr*> &corrs>){
std::vector<corr*> condensed;
#endif
condensed.resize(corrs.size());
condensed[0] =std::move(corrs[0]);
int J = 0;
bool flag;
for(size_t I=1;I<corrs.size(); I++){
flag = true;
for(int i =0; i<=J;i++){
if(compare_corr(condensed[i],corrs[I])){
flag = false;
break;
}
}
if(!flag) continue;
J++;
condensed[J] = std::move(corrs[I]);
if(condensed[J].get() ==nullptr || corrs[I].get()!=nullptr){
std::cerr << "what?" << std::endl;;
std::cerr << "condesed["<< J << "] :" << condensed[J].get() << std::endl;
std::cerr << "corrs: " << corrs[I].get() << std::endl;
exit(1);
}
}
corrs.clear(); // release the memory hold in corrs and bring its size to 0
corrs.reserve(J); // reserved enougth memory for J unique_ptr
condensed.resize(J); // keep the first J element of condensed, releasing the memory of all the others
for(auto& corr : condensed){
corrs.push_back(corr->make_unique_ptr());
}
}
#include <fstream>
#include <string>
#include <regex>
#include <iostream>
#include "../include/file_manip.h"
// parse the file until "section name" is found. file is left at the beginning of the section, that is right after the section name.
// section_name should not contain square brakets "[]"!!
//
// It assume that "section_name" is after the current position in the input stream.
// If you might have pass it, it is better to reset the input stream position to the beginning and then call find_section
void find_section(std::ifstream &file, const std::string& section_name){
std::string line;
while(!file.eof()){
std::getline(file, line);
if (line.find(section_name) !=std::string::npos) return;
}
std::cerr << "[find_section]: Section " << section_name << " not found!"<< std::endl;
exit(1);
}
void read_measurements(std::ifstream &file, std::vector<int> &par){
find_section(file,"Measurements");
std::string line;
std::regex rgx_int("[0-9]+");
read_line(file, line);
check_line(line, "nprop");
par[0] = std::stoi(get_match(line,rgx_int));
read_line(file, line);
check_line(line, "ncorr");
par[1] = std::stoi(get_match(line,rgx_int));
}
// read lines untill a non-comment line is found. a comment line is recognised if the first non-space character is '#'
void inline read_line(std::ifstream &file, std::string &line){
int i=0;
while(true){
std::getline(file,line);
while(std::isspace(line[i])){
i++;
}
if(line[i] !='#') return;
}
}
inline void check_line(const std::string& line,const std::string &name){
if(line[0]=='['|| line.empty()){
std::cerr << "[check_line] inputstream position is not where expected. make sure to call find_section() first. " << std::endl;
exit(1);
}
if(line.find(name)==std::string::npos){
std::cerr << "[check_line] " << name<< " field expected. Found " << line << std::endl;
exit(1);
}
}
inline std::string get_match(const std::string& line, const std::regex &rgx){
static std::smatch match;
if(!std::regex_search(line,match,rgx)){
std::cerr << "[get_match] No match in "<< line << std::endl;
exit(1);
}
return match.str(0);
}
std::vector<std::string> get_all_match(const std::string& line, const std::regex& rgx){
static std::smatch match;
if(!std::regex_search(line,match,rgx)){
std::cerr << "[get_all_match] No match in "<< line << std::endl;
exit(1);
}
std::vector<std::string> res{match.str(0)};
std::string aux = match.suffix();
while(std::regex_search(aux,match,rgx)){
res.push_back(match.str(0));
aux = match.suffix();
}
return res;
}
/*******************************************************************************
*
* File input_parser.cpp
*
* Copyright (C) 2025 D'Anna Antonino
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*******************************************************************************
*
* parsing of input files for meson.c, tm_meson.c in their latest version
* avaliable on Jul 2025. See README for details:
*
* input_parser.x <input_file1> ...
*
*******************************************************************************/
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <array>
#include <memory>
#include <algorithm>
#include <regex>
#include <time.h>
#include "../include/Gamma.h"
#include "../include/propagator.h"
#include "../include/correlator.h"
#include "../include/file_manip.h"
void parse_argv(const std::vector<std::string> &argv, std::string &output_dir, std::vector<std::string> &input_files){
input_files.reserve(argv.size()-1);
for(auto itr = std::next(argv.begin(),1); itr!=argv.end(); std::advance(itr,1)){
if(itr->compare(0,2,"-o")==0){
if(itr->length()==2){
std::advance(itr,1);
output_dir = *itr;
}
else {
output_dir = itr->substr(2,std::string::npos);
}
if(output_dir.back()!='/')
output_dir.push_back('/');
}
else{
input_files.push_back(*itr);
}
}
input_files.shrink_to_fit();
}
int main(int argc, char* argv[]){
if(argc<2){
std::cout << "Scalar mode not available." << std::endl;
std::cout << "Try: input_parser.x <input_file1> <input_file2> ... <input_filen>" << std::endl;
exit(1);
}
std::string output_dir{};
std::vector<std::string> input_filenames{};
parse_argv(std::vector<std::string>(argv,argv+argc),output_dir,input_filenames);
std::ifstream input_file;
std::ofstream output_file;
std::ofstream condense_file;
int ncorr, nprop;
std::vector<propagator> propagators;
std::vector<std::unique_ptr<corr>> correlators;
for(std::string filename : input_filenames){
input_file.open(filename);
if(!input_file.is_open()){
std::cerr << "Error: file "<< filename << " not found. Moving on..." << std::endl;
continue;
}
{
std::string aux{};
if (output_dir.size() !=0){
size_t idx = filename.find_last_of("/");
aux = output_dir + filename.substr(idx+1,std::string::npos);
}
else {
aux = filename;
}
size_t idx =aux.find_last_of(".");
aux = aux.substr(0,idx) + "_corr.txt";
output_file.open(aux);
if(!output_file.is_open()){
std::cerr << "Error: unable to open output file " << aux <<" . Moving on..." << std::endl;
input_file.close();
continue;
}
aux = aux.substr(0,idx) +"_condese_corr.txt";
condense_file.open(aux);
if(!condense_file.is_open()){
std::cerr << "Error: unable to open condense file "<< aux << ". No condense file will be produced"<< std::endl;
}
}
std::vector<int> aux= {0,0};
read_measurements(input_file,aux);
nprop = aux[0];
ncorr = aux[1];
propagators.clear();
propagators.resize(nprop);
read_all_propagator(input_file, propagators, nprop);
read_all_corr(input_file,correlators,propagators, ncorr);
for(int i=0; i<ncorr; i++){
output_file << "[Correlator "<< i << " ]"<< std::endl;
correlators[i]->print(output_file);
output_file << std::endl;
}
condense_correlator(correlators);
for(auto& corr : correlators){
corr->print(condense_file);
condense_file << std::endl;
}
input_file.close();
output_file.close();
condense_file.close();
}
}
##
# Input Parser
#
# @file
# @version 0.1
OBJECT_DIR = ../bin
HEADERS_DIR = ../include
SRC_DIR = .
MAIN = input_parser.cpp
SRC_FILES = correlator.cpp file_manip.cpp propagator.cpp
HEADERS_FILES = Gamma.h correlator.h file_manip.h propagator.h
SRC = $(SRC_FILES:%.cpp= $(SRC_DIR)/%.cpp)
HEADERS = $(HEADERS_FILES:%.h= $(HEADERS_DIR)/%.h)
OBJECT = $(SRC:%.cpp= $(OBJECT_DIR)/%.o)
OBJECT_11 = $(SRC:%.cpp= $(OBJECT_DIR)/%.o)
CXX = g++
CFLAGS = -c
LDFLAGS = #-Wall -Wpedantic -Wextra -Werror -fsanitize=address
STD = -std=c++17
input.x: $(MAIN) $(OBJECT) $(HEADERS)
$(CXX) $(STD) $(LDFLAGS) $(MAIN) $(OBJECT) -o $@
$(OBJECT): $(OBJECT_DIR)/%.o: %.cpp
@if [ ! -d $(OBJECT_DIR) ]; then mkdir $(OBJECT_DIR); fi
$(CXX) $(STD) $(CFLAGS) $(LDFLAGS) $< -o $@
clean:
@rm -f $(OBJECT_DIR)/*.o
@echo make clean: done
# end
#include <iostream>
#include "../include/Gamma.h"
#include "../include/file_manip.h"
#include "../include/propagator.h"
std::ostream& operator<<(std::ostream& os, const propagator &prop){
os << "kappa : " << prop.kappa << std::endl;
os << "mu : " << prop.mu << std::endl;
os << "theta : ";
for(auto t : prop.theta)
os << t << " ";
os << std::endl;
if(prop.seq_prop){
os << "sequential propagator: " << std::endl;
os << "seq_id: " << prop.seq_id << std::endl;
os << "Gamma: " << prop.seq_type << std::endl;
os << "source: " << prop.src << std::endl;
}
return os;
}
void read_all_propagator(std::ifstream &file, std::vector<propagator>& props, int nprop){
props.clear();
props.resize(nprop);
std::string temp;
std::vector<std::string> vtemp;
std::regex rgx_double("\\s[+-]?([0-9]*[.])?[0-9]+");
std::regex rgx_int("\\s[+-]?[0-9]+");
std::regex rgx_double_int("\\s[+-]?[0-9]*([.]*[0-9]+)");
std::regex rgx_gamma("(G[0-5]){1,2}");
for(int i=0; i<nprop; i++){
find_section(file, "Propagator "+std::to_string(i));
read_line(file,temp);
check_line(temp,"kappa");
props[i].kappa = std::stod(get_match(temp,rgx_double));
read_line(file,temp);
check_line(temp,"mus");
props[i].mu = std::stod(get_match(temp,rgx_double));
read_line(file,temp);
check_line(temp,"theta");
vtemp = get_all_match(temp,rgx_double_int);
for(unsigned j=0; j<3; j++){
//std::cout<< "ok"<< std::endl;
props[i].theta[j] = std::stod(vtemp[j]);
}
read_line(file,temp);
if(temp.empty()) return;
if(temp[0]=='['){
std::cerr << "[read_propagator] inputstream position moved too far." << std::endl;
exit(1);
}
if (temp.find("seq_prop")!= std::string::npos){
props[i].seq_prop=true;
props[i].seq_id=std::stoi(get_match(temp,rgx_int));
read_line(file,temp);
check_line(temp,"seq_type");
props[i].seq_type = stog(get_match(temp,rgx_gamma));
read_line(file,temp);
check_line(temp,"seq_x0");
props[i].src = std::stoi(get_match(temp,rgx_int));
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment