19 #define ERROR(x) throw std::runtime_error(string("Error in file ")+__FILE__+" at line "+to_string(__LINE__)+" (in "+__func__+"): "+x); 20 #define DBG(x) std::cout << "In " << __FILE__ << " at line " << __LINE__ << " (in function " << __func__ << "): " << x << std::endl; 33 int main(
int argc,
char *argv[]){
35 for(
int argi = 1; argi < argc; ++argi){
36 files.insert(argv[argi]);
42 for(
const auto &file: files){
94 if(var.second !=
"")
return var.second;
125 string type =
Type();
126 if(type.find(
"std::") != string::npos){
143 string type =
Type(baby_type);
144 if(type.find(
"std::") != string::npos){
181 return type_set.size()==1 && *(type_set.cbegin()) !=
"";
197 if(type_set.size() != 2)
return false;
198 auto iter = type_set.cbegin();
199 string first_type = *iter;
201 string second_type = *iter;
202 return (first_type !=
"" && second_type ==
"")
203 || (first_type ==
"" && second_type !=
"");
227 if(type_set.size() == 2){
228 auto iter = type_set.cbegin();
229 string first_type = *iter;
231 string second_type = *iter;
232 return (first_type != second_type)
233 && (first_type !=
"")
234 && (second_type !=
"");
236 return type_set.size() >= 3;
273 types.insert(type.second);
286 vector<Variable> vars;
287 for(
const auto &file: files){
288 ifstream ifs(
"txt/variables/"+file);
289 for(
string line; std::getline(ifs, line); ){
293 vector<Variable>::iterator this_var = vars.end();
294 for(
auto iter = vars.begin();
297 if(iter->Name() == var.
Name()) this_var = iter;
299 if(this_var != vars.end()){
300 this_var->SetEntry(file, simple_var.
type_);
308 for(
auto &var: vars){
309 for(
const auto &file: files){
310 if(!var.HasEntry(file)) var.SetEntry(file,
"");
314 return {vars.cbegin(), vars.cend()};
326 if(line.size() <= 2)
return true;
327 for(
const auto &letter: line){
328 if(letter ==
' ')
continue;
329 if(isalpha(letter) || letter ==
'_'){
346 auto loc = line.rfind(
';');
347 if(loc != string::npos) line = line.substr(0,loc);
348 loc = line.rfind(
' ');
349 if(loc == string::npos){
350 ERROR(
"Could not separate type and variable in "+line);
362 size_t loc = line.find_first_not_of(
" ");
363 if(loc != string::npos){
364 line = line.substr(loc);
366 while((loc = line.find(
" ", loc)) != string::npos){
367 line.replace(loc, 2,
" ");
370 loc = line.find_last_not_of(
" ");
371 if(loc != string::npos){
372 line = line.substr(0, loc+1);
384 for(
size_t i = 0; i < x.size(); ++i){
385 x.at(i) = toupper(x.at(i));
398 for(
size_t i = 0; i < x.size(); ++i){
399 x.at(i) = tolower(x.at(i));
411 const set<string> &types){
412 ofstream file(
"inc/core/baby.hpp");
413 file <<
"#ifndef H_BABY\n";
414 file <<
"#define H_BABY\n\n";
416 file <<
"#include <vector>\n";
417 file <<
"#include <set>\n";
418 file <<
"#include <memory>\n";
419 file <<
"#include <string>\n\n";
421 file <<
"#include \"TChain.h\"\n\n";
422 file <<
"#include \"TString.h\"\n\n";
424 file <<
"class Process;\n";
425 file <<
"class NamedFunc;\n\n";
427 file <<
"class Baby{\n";
428 file <<
"private:\n";
429 file <<
" class Activator{\n";
430 file <<
" public:\n";
431 file <<
" Activator(Baby &baby);\n";
432 file <<
" ~Activator();\n\n";
434 file <<
" private:\n";
435 file <<
" Baby & baby_;\n\n";
437 file <<
" Activator(const Activator &) = delete;\n";
438 file <<
" Activator & operator=(const Activator &) = delete;\n";
439 file <<
" Activator(Activator &&) = delete;\n";
440 file <<
" Activator & operator=(Activator &&) = delete;\n";
444 file <<
" explicit Baby(const std::set<std::string> &file_names,\n";
445 file <<
" const std::set<const Process*> &processes = std::set<const Process*>{});\n";
446 file <<
" Baby(Baby &&) = default;\n";
447 file <<
" Baby& operator=(Baby &&) = default;\n";
448 file <<
" virtual ~Baby() = default;\n\n";
450 file <<
" long GetEntries() const;\n";
451 file <<
" virtual void GetEntry(long entry);\n\n";
453 file <<
" const std::set<std::string> & FileNames() const;\n\n";
454 file <<
" int SampleType() const;\n";
455 file <<
" int SetSampleType(const TString &filename);\n\n";
457 file <<
" std::set<const Process*> processes_;\n\n";
459 for(
const auto &var: vars){
460 if(var.ImplementInBase()){
462 << var.DecoratedType() <<
" const & " 463 << var.Name() <<
"() const;\n";
464 }
else if(var.VirtualInBase()){
466 << var.DecoratedType() <<
" const & " 467 << var.Name() <<
"() const = 0;\n";
472 file <<
" const std::unique_ptr<TChain> & GetTree() const;\n\n";
474 file <<
" static NamedFunc GetFunction(const std::string &var_name);\n\n";
476 file <<
" std::unique_ptr<Activator> Activate();\n\n";
478 file <<
"protected:\n";
479 file <<
" virtual void Initialize();\n\n";
481 file <<
" std::unique_ptr<TChain> chain_;//!<Chain to load variables from\n";
482 file <<
" long entry_;//!<Current entry\n\n";
484 file <<
"private:\n";
485 file <<
" friend class Activator;\n\n";
487 file <<
" Baby() = delete;\n";
488 file <<
" Baby(const Baby &) = delete;\n";
489 file <<
" Baby& operator=(const Baby &) = delete;\n\n";
491 file <<
" std::set<std::string> file_names_;//!<Files loaded into TChain\n";
492 file <<
" int sample_type_;//!< Integer indicating what kind of sample the first file has\n";
493 file <<
" mutable long total_entries_;//!<Cached number of events in TChain\n";
494 file <<
" mutable bool cached_total_entries_;//!<Flag if cached event count up to date\n\n";
496 file <<
" void ActivateChain();\n";
497 file <<
" void DeactivateChain();\n\n";
499 for(
const auto &var: vars){
500 if(!var.ImplementInBase())
continue;
502 << var.DecoratedType() <<
" " 503 << var.Name() <<
"_;//!<Cached value of " << var.Name() <<
'\n';
504 file <<
" TBranch *b_" << var.Name() <<
"_;//!<Branch from which " 505 << var.Name() <<
" is read\n";
506 file <<
" mutable bool c_" << var.Name() <<
"_;//!<Flag if cached " 507 << var.Name() <<
" up to date\n";
511 for(
const auto &type: types){
512 file <<
"#include \"core/baby_" << type <<
".hpp\"\n";
516 file <<
"#endif" << endl;
525 ofstream file(
"src/core/baby.cpp");
526 file <<
"/*! \\class Baby\n\n";
528 file <<
" \\brief Abstract base class for access to ntuple variables\n\n";
530 file <<
" Loads variables on demand and caches for fast repeated use within an event.\n\n";
532 file <<
" A derived class is used for each known ntuple format. Variables and functions\n";
533 file <<
" are kept in this base class whenever possible, and placed in the derived classes\n";
534 file <<
" only when necessary. All variables that are identical across derived Baby\n";
535 file <<
" classes are implemented fully in this base class. Others are implemented with\n";
536 file <<
" dummy virtual accessor functions and internal member variables in the base\n";
537 file <<
" class, with derived classes providing a real implementation of the accessor if\n";
538 file <<
" the variable is defined in the corresponding ntuple format. If the variable has\n";
539 file <<
" inconsistent types across the ntuple formats, then each derived class must\n";
540 file <<
" provide all necessary accessors and internal variables; in such a case, access\n";
541 file <<
" through this abstract base is not possible.\n";
544 file <<
"#include \"core/baby.hpp\"\n\n";
546 file <<
"#include <mutex>\n";
547 file <<
"#include <type_traits>\n";
548 file <<
"#include <utility>\n";
549 file <<
"#include <stdexcept>\n\n";
551 file <<
"#include \"core/named_func.hpp\"\n";
552 file <<
"#include \"core/utilities.hpp\"\n\n";
554 file <<
"using namespace std;\n\n";
556 file <<
"namespace{\n";
557 file <<
" using ScalarType = NamedFunc::ScalarType;\n";
558 file <<
" using VectorType = NamedFunc::VectorType;\n";
559 file <<
" using ScalarFunc = NamedFunc::ScalarFunc;\n";
560 file <<
" using VectorFunc = NamedFunc::VectorFunc;\n\n";
562 file <<
" /*!\\brief Get dummy NamedFunc in case of substitution failure\n\n";
564 file <<
" \\param[in] name Name of function/variable\n\n";
566 file <<
" \\return Dummy NamedFunc that always returns 0\n";
568 file <<
" template<typename T>\n";
569 file <<
" NamedFunc GetFunction(T,\n";
570 file <<
" const string &name){\n";
571 file <<
" DBG(\"Could not find appropriate type for \\\"\" << name << \".\\\"\");\n";
572 file <<
" return NamedFunc(name, [](const Baby &){return 0.;}, false);\n";
575 file <<
" /*!\\brief Get NamedFunc for a function returning a scalar\n\n";
577 file <<
" \\param[in] baby_func Member function pointer to variable accessor\n\n";
579 file <<
" \\param[in] name Name of function/variable\n\n";
581 file <<
" \\return NamedFunc that returns appropriate scalar\n";
583 file <<
" template<typename T>\n";
584 file <<
" NamedFunc GetFunction(T const &(Baby::*baby_func)() const,\n";
585 file <<
" const string &name){\n";
586 file <<
" return NamedFunc(name,\n";
587 file <<
" [baby_func](const Baby &b){\n";
588 file <<
" return ScalarType((b.*baby_func)());\n";
592 file <<
" /*!\\brief Get NamedFunc for a function returning a vector\n\n";
594 file <<
" \\param[in] baby_func Member function pointer to variable accessor\n\n";
596 file <<
" \\param[in] name Name of function/variable\n\n";
598 file <<
" \\return NamedFunc that returns appropriate vectorr\n";
600 file <<
" template<typename T>\n";
601 file <<
" NamedFunc GetFunction(vector<T>* const &(Baby::*baby_func)() const,\n";
602 file <<
" const string &name){\n";
603 file <<
" return NamedFunc(name,\n";
604 file <<
" [baby_func](const Baby &b){\n";
605 file <<
" const auto &raw = (b.*baby_func)();\n";
606 file <<
" return VectorType(raw->cbegin(), raw->cend());\n";
610 bool have_vector_double =
false;
611 for(
auto var = vars.cbegin(); var != vars.cend() && !have_vector_double; ++var){
612 if(var->Type().find(
"vector<double>") != string::npos){
613 have_vector_double =
true;
617 if(have_vector_double){
618 file <<
" template<>\n";
619 file <<
" NamedFunc GetFunction<vector<double>* const &(Baby::*)() const>(vector<double>* const &(Baby::*baby_func)() const,\n";
620 file <<
" const string &name){\n";
621 file <<
" return NamedFunc(name, [baby_func](const Baby &b){return *((b.*baby_func)());}, true);\n";
626 file <<
"Baby::Activator::Activator(Baby &baby):\n";
627 file <<
" baby_(baby){\n";
628 file <<
" baby_.ActivateChain();\n";
631 file <<
"Baby::Activator::~Activator(){\n";
632 file <<
" baby_.DeactivateChain();\n";
635 file <<
"/*!\\brief Standard constructor\n\n";
637 file <<
" \\param[in] file_names ntuple files to read from\n";
639 file <<
"Baby::Baby(const set<string> &file_names,\n";
640 file <<
" const set<const Process*> &processes):\n";
641 file <<
" processes_(processes),\n";
642 file <<
" chain_(nullptr),\n";
643 file <<
" file_names_(file_names),\n";
644 file <<
" total_entries_(0),\n";
645 auto last_base = vars.cbegin();
646 bool found_in_base =
false;
647 for(
auto iter = vars.cbegin(); iter != vars.cend(); ++iter){
648 if(iter->ImplementInBase()){
650 found_in_base =
true;
653 if(vars.size() == 0 || !found_in_base){
654 file <<
" cached_total_entries_(false){\n";
656 file <<
" cached_total_entries_(false),\n";
657 for(
auto var = vars.cbegin(); var != last_base; ++var){
658 if(!var->ImplementInBase())
continue;
659 file <<
" " << var->Name() <<
"_{},\n";
660 file <<
" b_" << var->Name() <<
"_(nullptr),\n";
661 file <<
" c_" << var->Name() <<
"_(false),\n";
663 file <<
" " << last_base->Name() <<
"_{},\n";
664 file <<
" b_" << last_base->Name() <<
"_(nullptr),\n";
665 file <<
" c_" << last_base->Name() <<
"_(false){\n";
667 file <<
" TString filename=\"\";\n";
668 file <<
" if(file_names_.size()) filename = *file_names_.cbegin();\n";
669 file <<
" sample_type_ = SetSampleType(filename);\n";
672 file <<
"/*!\\brief Get number of entries in TChain and cache it\n\n";
674 file <<
" \\return Number of entries in TChain\n";
676 file <<
"long Baby::GetEntries() const{\n";
677 file <<
" if(!cached_total_entries_){\n";
678 file <<
" cached_total_entries_ = true;\n";
679 file <<
" lock_guard<mutex> lock(Multithreading::root_mutex);\n";
680 file <<
" total_entries_ = chain_->GetEntries();\n";
682 file <<
" return total_entries_;\n";
685 file <<
"/*!\\brief Change current entry\n\n";
687 file <<
" \\param[in] entry Entry number to load\n";
689 file <<
"void Baby::GetEntry(long entry){\n";
690 for(
const auto &var: vars){
691 if(!var.ImplementInBase())
continue;
692 file <<
" c_" << var.Name() <<
"_ = false;\n";
694 file <<
" lock_guard<mutex> lock(Multithreading::root_mutex);\n";
695 file <<
" entry_ = chain_->LoadTree(entry);\n";
698 file <<
"const std::set<std::string> & Baby::FileNames() const{\n";
699 file <<
" return file_names_;\n";
702 file <<
"// Return integer with sample type\n";
703 file <<
"int Baby::SampleType() const{\n";
704 file <<
" return sample_type_;\n";
707 file <<
"int Baby::SetSampleType(const TString &filename){\n";
708 file <<
" int st = 0;\n";
709 file <<
" if(filename.Contains(\"SMS\")) st = 10;\n";
710 file <<
" if(filename.Contains(\"_TTJets\")) st = 20;\n";
711 file <<
" if(filename.Contains(\"_WJets\")) st = 30;\n";
712 file <<
" if(filename.Contains(\"DYJets\")) st = 40;\n";
713 file <<
" if(filename.Contains(\"_ZJets\")) st = 41;\n";
714 file <<
" if(filename.Contains(\"_ST_\")) st = 50;\n";
715 file <<
" if(filename.Contains(\"_QCD\")) st = 60;\n";
716 file <<
" if(filename.Contains(\"_TTWJets\"))st = 70;\n";
717 file <<
" if(filename.Contains(\"_TTZ\")) st = 71;\n";
718 file <<
" if(filename.Contains(\"_TTG\")) st = 72;\n";
719 file <<
" return st;\n";
722 file <<
"/*! \\brief Get underlying TChain for this Baby\n\n";
724 file <<
" \\return Pointer to underlying TChain\n";
726 file <<
"const unique_ptr<TChain> & Baby::GetTree() const{\n";
727 file <<
" return chain_;\n";
730 file <<
"/*! \\brief Get a NamedFunc accessing specified variable\n\n";
732 file <<
" \\return NamedFunc which returns specified variable from a Baby\n";
734 file <<
"NamedFunc Baby::GetFunction(const std::string &var_name){\n";
735 if(vars.size() != 0){
736 file <<
" if(var_name == \"" << vars.cbegin()->Name() <<
"\"){\n";
737 file <<
" return ::GetFunction(&Baby::" << vars.cbegin()->Name() <<
", \"" << vars.cbegin()->Name() <<
"\");\n";
738 for(
auto var = ++vars.cbegin(); var != vars.cend(); ++var){
739 file <<
" }else if(var_name == \"" << var->Name() <<
"\"){\n";
740 file <<
" return ::GetFunction(&Baby::" << var->Name() <<
", \"" << var->Name() <<
"\");\n";
743 file <<
" DBG(\"Function lookup failed for \\\"\" << var_name << \"\\\"\");\n";
744 file <<
" return NamedFunc(var_name,\n";
745 file <<
" [](const Baby &){\n";
746 file <<
" return 0.;\n";
750 file <<
" DBG(\"No variables defined in Baby.\");\n";
751 file <<
" return NamedFunc(var_name,\n";
752 file <<
" [](const Baby &){\n";
753 file <<
" return 0.;\n";
758 file <<
"unique_ptr<Baby::Activator> Baby::Activate(){\n";
759 file <<
" return unique_ptr<Baby::Activator>(new Baby::Activator(*this));\n";
762 file <<
"/*! \\brief Setup all branches\n";
764 file <<
"void Baby::Initialize(){\n";
765 file <<
" chain_->SetMakeClass(1);\n";
766 for(
const auto &var: vars){
767 if(!var.ImplementInBase())
continue;
768 file <<
" chain_->SetBranchAddress(\"" << var.Name() <<
"\", &" << var.Name() <<
"_, &b_" << var.Name() <<
"_);\n";
772 file <<
"void Baby::ActivateChain(){\n";
773 file <<
" if(chain_) ERROR(\"Chain has already been initialized\");\n";
774 file <<
" lock_guard<mutex> lock(Multithreading::root_mutex);\n";
775 file <<
" chain_ = unique_ptr<TChain>(new TChain(\"tree\"));\n";
776 file <<
" for(const auto &file: file_names_){\n";
777 file <<
" chain_->Add(file.c_str());\n";
779 file <<
" Initialize();\n";
782 file <<
"void Baby::DeactivateChain(){\n";
783 file <<
" lock_guard<mutex> lock(Multithreading::root_mutex);\n";
784 file <<
" chain_.reset();\n";
787 for(
const auto &var: vars){
788 if(!var.ImplementInBase())
continue;
789 file <<
"/*! \\brief Get " << var.Name() <<
" for current event and cache it\n\n";
791 file <<
" \\return " << var.Name() <<
" for current event\n";
793 file << var.DecoratedType() <<
" const & Baby::" << var.Name() <<
"() const{\n";
794 file <<
" if(!c_" << var.Name() <<
"_ && b_" << var.Name() <<
"_){\n";
795 file <<
" b_" << var.Name() <<
"_->GetEntry(entry_);\n";
796 file <<
" c_" << var.Name() <<
"_ = true;\n";
798 file <<
" return " << var.Name() <<
"_;\n";
812 ofstream file(
"inc/core/baby_"+type+
".hpp");
813 file <<
"#ifndef H_BABY_" <<
ToUpper(type) <<
"\n";
814 file <<
"#define H_BABY_" <<
ToUpper(type) <<
"\n\n";
816 file <<
"#include \"core/baby.hpp\"\n\n";
818 file <<
"class Baby_" << type <<
": virtual public Baby{\n";
820 file <<
" explicit Baby_" << type <<
"(const std::set<std::string> &file_names, const std::set<const Process*> &processes = std::set<const Process*>{});\n";
821 file <<
" virtual ~Baby_" << type <<
"() = default;\n\n";
823 file <<
" virtual void GetEntry(long entry);\n\n";
825 for(
const auto &var: vars){
826 if(var.VirtualInBase()){
827 if(var.ImplementIn(type)){
828 file <<
" virtual " << var.DecoratedType() <<
" const & " << var.Name() <<
"() const;\n";
830 file <<
" __attribute__((noreturn)) virtual " << var.DecoratedType()
831 <<
" const & " << var.Name() <<
"() const;\n";
833 }
else if(var.EverythingIn(type)){
834 file <<
" " << var.DecoratedType(type) <<
" const & " << var.Name() <<
"() const;\n";
839 file <<
"private:\n";
840 file <<
" Baby_" << type <<
"() = delete;\n";
841 file <<
" Baby_" << type <<
"(const Baby_" << type <<
" &) = delete;\n";
842 file <<
" Baby_" << type <<
"& operator=(const Baby_" << type <<
" &) = delete;\n";
843 file <<
" Baby_" << type <<
"(Baby_" << type <<
" &&) = delete;\n";
844 file <<
" Baby_" << type <<
"& operator=(Baby_" << type <<
" &&) = delete;\n";
846 file <<
" virtual void Initialize();\n\n";
848 for(
const auto &var: vars){
849 if(var.ImplementIn(type) || var.EverythingIn(type)){
850 file <<
" " << var.DecoratedType(type) <<
" " 851 << var.Name() <<
"_;//!<Cached value of " << var.Name() <<
'\n';
852 file <<
" TBranch *b_" << var.Name() <<
"_;\n//!<Branch from which " 853 << var.Name() <<
" is read\n";
854 file <<
" mutable bool c_" << var.Name() <<
"_;//!<Flag if cached " 855 << var.Name() <<
" up to date\n";
860 file <<
"#endif" << endl;
872 ofstream file(
"src/core/baby_"+type+
".cpp");
873 file <<
"/*! \\class Baby_" << type <<
"\n\n";
875 file <<
" \\brief Derived class to access variables in " << type <<
" format ntuples\n\n";
877 file <<
" For variables not shared by all ntuple formats, the abstract base class Baby\n";
878 file <<
" cannot implement functions to get them, and derived classes must do the work.\n";
879 file <<
" This class implements getter functions for variables in the " << type <<
" format\n";
880 file <<
" ntuples, and dummy getters that throw an error for any variable not in " << type;
881 file <<
" format ntuples.\n";
883 file <<
"#include \"core/baby_" << type <<
".hpp\"\n\n";
885 file <<
"#include \"core/utilities.hpp\"\n\n";
887 file <<
"using namespace std;\n\n";
889 file <<
"/*!\\brief Standard constructor\n\n";
891 file <<
" \\param[in] file_names ntuple files to read from\n";
893 file <<
"Baby_" << type <<
"::Baby_" << type <<
"(const set<string> &file_names, const set<const Process*> &processes):\n";
894 int implemented_here = 0;
895 for(
const auto & var: vars){
896 if(var.ImplementIn(type) || var.EverythingIn(type)) ++implemented_here;
898 if(implemented_here == 0){
899 file <<
" Baby(file_names, processes){\n";
901 file <<
" Baby(file_names, processes),\n";
902 set<Variable>::const_iterator last = vars.cend();
903 for(
auto var = vars.cbegin(); var != vars.cend(); ++var){
904 if(var->ImplementIn(type) || var->EverythingIn(type)){
908 for(
auto var = vars.cbegin(); var != vars.cend(); ++var){
909 if(var->ImplementIn(type) || var->EverythingIn(type)){
910 file <<
" " << var->Name() <<
"_{},\n";
911 file <<
" b_" << var->Name() <<
"_(nullptr),\n";
913 file <<
" c_" << var->Name() <<
"_(false),\n";
915 file <<
" c_" << var->Name() <<
"_(false){\n";
922 file <<
"/*!\\brief Change current entry\n\n";
924 file <<
" \\param[in] entry Entry number to load\n";
926 file <<
"void Baby_" << type <<
"::GetEntry(long entry){\n";
927 for(
const auto &var: vars){
928 if(var.ImplementIn(type) || var.EverythingIn(type)){
929 file <<
" c_" << var.Name() <<
"_ = false;\n";
932 file <<
" Baby::GetEntry(entry);\n";
935 file <<
"/*! \\brief Setup all branches\n";
937 file <<
"void Baby_" << type <<
"::Initialize(){\n";
938 file <<
" Baby::Initialize();\n";
939 for(
const auto &var: vars){
940 if(var.ImplementIn(type) || var.EverythingIn(type)){
941 file <<
" chain_->SetBranchAddress(\"" << var.Name() <<
"\", &" 942 << var.Name() <<
"_, &b_" << var.Name() <<
"_);\n";
947 for(
const auto &var: vars){
948 if(var.ImplementIn(type) || var.EverythingIn(type)){
949 file <<
"/*!\\brief Get " << var.Name() <<
" for current event and cache it\n\n";
951 file <<
" \\return " << var.Name() <<
" for current event\n";
953 file << var.DecoratedType(type) <<
" const & Baby_" << type <<
"::" << var.Name() <<
"() const{\n";
954 file <<
" if(!c_" << var.Name() <<
"_ && b_" << var.Name() <<
"_){\n";
955 file <<
" b_" << var.Name() <<
"_->GetEntry(entry_);\n";
956 file <<
" c_" << var.Name() <<
"_ = true;\n";
958 file <<
" return " << var.Name() <<
"_;\n";
960 }
else if(var.VirtualInBase()){
961 file <<
"/*!\\brief Dummy getter for " << var.Name() <<
". Throws error\n\n";
963 file <<
" \\return Never returns. Throws error.\n";
965 file << var.DecoratedType() <<
" const & Baby_" << type <<
"::" << var.Name() <<
"() const{\n";
966 file <<
" ERROR(\"" << var.DecoratedType() <<
' ' << var.Name()
967 <<
" not available in babies of type " << type <<
".\");\n";
bool ImplementIn(const std::string &baby_type) const
Check if variable needs accessor implemented in a derived Baby class.
set< Variable > GetVariables(const set< string > &files)
void WriteSpecializedSource(const set< Variable > &vars, const string &type)
Writes a derived Baby source file.
bool VirtualInBase() const
Check if variable should have pure virtual method in Baby.
bool HasEntry(const std::string &baby_type) const
Check if a derived Baby class has this variable.
SimpleVariable(const std::string &type, const std::string &name)
Standard constructor.
bool EverythingIn(const std::string &baby_type) const
Check if variable needs declaration and definition in a derived class.
bool ImplementInBase() const
Check if variable can be implemented directly in Baby.
std::string type_
Type of variable (e.g., int, float, etc.)
const std::string & Name() const
Get variable name.
void RemoveExtraSpaces(string &line)
Removes leading, trailing, and double spaced from a text line.
void SetEntry(const std::string &baby_type, const std::string &type)
Set the type of this variable for use in a derived Baby class.
void WriteBaseSource(const set< Variable > &vars)
Writes src/baby.cpp.
std::set< std::string > GetTypeSet() const
Get all types (int, float, etc.) used across derived Baby classes.
std::string DecoratedType() const
Get type with "std::" and "*" if needed.
bool NotInBase() const
Check if variable is completely absent in base Baby.
Pairs a type and name of a variable accessible via Baby.
std::string Type() const
Get one type for variable across all Baby classes.
bool IsComment(const string &line)
Check if line in variable list file is a comment (blank)
std::map< std::string, std::string > type_map_
Map from Baby type (basic, full, etc.) to variabl type (int, float, etc.)
std::string name_
Name of variable (e.g., ht, met, etc.)
string ToLower(string x)
Replaces all upper case letters with lower case equivalent.
bool operator<(const Variable &other) const
Comparison operator allows storing Variable in set.
void WriteBaseHeader(const set< Variable > &vars, const set< string > &types)
Writes inc/baby.hpp.
Variable(const std::string &name)
Standard constructor.
void WriteSpecializedHeader(const set< Variable > &vars, const string &type)
Writes a derived Baby header file.
std::string name_
Name of variable (e.g., ht, met, etc.)
A variable to be accessible in Baby classes.
string ToUpper(string x)
Replaces all lower case letters with upper case equivalent.
SimpleVariable GetVariable(string line)
Extracts variable type and name from line from variable text files.
int main(int argc, char *argv[])