8#include "phoenix_color.h"
9#include "openFileStream.h"
20 const std::vector<PClassAttribute> & listAttr(classConfig.
getListAttribute());
21 for(std::vector<PClassAttribute>::const_iterator it(listAttr.begin()); it != listAttr.end(); ++it){
32 if(listTemplate.size() == 0LU){
return "";}
33 PString defTemplate(
"<"), comma(
"");
34 for(PVecString::const_iterator it(listTemplate.begin()); it != listTemplate.end(); ++it){
35 PVecString vecPart = it->split(
' ');
36 if(vecPart.size() != 0LU){
37 defTemplate += comma + vecPart.back();
50 if(listTemplate.size() == 0LU){
return "";}
51 PString templateDef(
"template<");
53 for(PVecString::const_iterator it(listTemplate.begin()); it != listTemplate.end(); ++it){
68 PString varType(attr.
getType());
71 if(defaultValue !=
""){
return "{" + defaultValue +
"}";}
80 bool hasDefaultValue =
false;
81 for(std::vector<PClassAttribute>::const_iterator it(vecAttr.begin()); it != vecAttr.end() && !hasDefaultValue; ++it){
82 hasDefaultValue |= it->getDefaultValue() !=
"";
84 return hasDefaultValue;
98 PString name(classConfig.
getName());
99 const std::vector<PClassAttribute> & listAttr(classConfig.
getListAttribute());
102 fs <<
"///Destructor of class " << name << std::endl;
103 fs << templateDeclaration;
104 fs << name << defTemplate <<
"::~" << name <<
"(){" << std::endl;
105 for(std::vector<PClassAttribute>::const_iterator it(listAttr.begin()); it != listAttr.end(); ++it){
107 fs <<
"\tdelete p_" << it->getName() <<
";" << std::endl;
110 fs <<
"}" << std::endl << std::endl;
113 fs <<
"///Copy constructor of class " << name << std::endl;
114 fs <<
"/**\t@param other : " << name <<
" we want to copy" << std::endl;
115 fs <<
"*/" << std::endl;
116 fs << templateDeclaration;
117 fs << name << defTemplate <<
"::" << name <<
"(const " << name << defTemplate <<
" & other)";
118 PString initListComma(
" : ");
119 for(std::vector<PClassAttribute>::const_iterator it(listAttr.begin()); it != listAttr.end(); ++it){
121 fs << initListComma <<
"p_" << it->getName() <<
"(NULL)";
122 initListComma =
", ";
125 fs <<
"{" << std::endl;
126 fs <<
"\tcopy" << name <<
"(other);" << std::endl;
127 fs <<
"}" << std::endl << std::endl;
130 fs <<
"///Copy assignment operator of class " << name << std::endl;
131 fs <<
"/**\t@param other : " << name <<
" we want to copy" << std::endl;
132 fs <<
" * \t@return copied class " << name << std::endl;
133 fs <<
"*/" << std::endl;
134 fs << templateDeclaration;
135 fs << name << defTemplate <<
" & " << name << defTemplate <<
"::operator = (const " << name << defTemplate <<
" & other){" << std::endl;
136 fs <<
"\tcopy" << name <<
"(other);" << std::endl;
137 fs <<
"\treturn *this;" << std::endl;
138 fs <<
"}" << std::endl << std::endl;
141 fs <<
"///Copy the attributes of class " << name << std::endl;
142 fs <<
"/**\t@param other : " << name <<
" we want to copy" << std::endl;
143 fs <<
"*/" << std::endl;
144 fs << templateDeclaration;
145 fs <<
"void " << name << defTemplate <<
"::copy" << name <<
"(const " << name << defTemplate <<
" & other){" << std::endl;
146 fs <<
"\tif(this == &other){return;}" << std::endl;
147 for(std::vector<PClassAttribute>::const_iterator it(listAttr.begin()); it != listAttr.end(); ++it){
149 PString pointeeType(it->getType().eraseFirstLastChar(
" \n\t*"));
150 fs <<
"\tdelete p_" << it->getName() <<
";" << std::endl;
151 fs <<
"\tp_" << it->getName() <<
" = other.p_" << it->getName() <<
" ? new " << pointeeType <<
"(*other.p_" << it->getName() <<
") : NULL;" << std::endl;
153 fs <<
"\tp_" << it->getName() <<
" = other.p_" << it->getName() <<
";" << std::endl;
156 fs <<
"}" << std::endl << std::endl;
159 fs <<
"///Move constructor of class " << name << std::endl;
160 fs <<
"/**\t@param other : " << name <<
" we want to move" << std::endl;
161 fs <<
"*/" << std::endl;
162 fs << templateDeclaration;
163 fs << name << defTemplate <<
"::" << name <<
"(" << name << defTemplate <<
" && other) noexcept";
164 initListComma =
" : ";
165 for(std::vector<PClassAttribute>::const_iterator it(listAttr.begin()); it != listAttr.end(); ++it){
167 fs << initListComma <<
"p_" << it->getName() <<
"(NULL)";
168 initListComma =
", ";
171 fs <<
"{" << std::endl;
172 fs <<
"\tmove" << name <<
"(std::move(other));" << std::endl;
173 fs <<
"}" << std::endl << std::endl;
176 fs <<
"///Move assignment operator of class " << name << std::endl;
177 fs <<
"/**\t@param other : " << name <<
" we want to move" << std::endl;
178 fs <<
" * \t@return moved class " << name << std::endl;
179 fs <<
"*/" << std::endl;
180 fs << templateDeclaration;
181 fs << name << defTemplate <<
" & " << name << defTemplate <<
"::operator = (" << name << defTemplate <<
" && other) noexcept{" << std::endl;
182 fs <<
"\tmove" << name <<
"(std::move(other));" << std::endl;
183 fs <<
"\treturn *this;" << std::endl;
184 fs <<
"}" << std::endl << std::endl;
187 fs <<
"///Move the attributes of class " << name << std::endl;
188 fs <<
"/**\t@param other : " << name <<
" we want to move" << std::endl;
189 fs <<
"*/" << std::endl;
190 fs << templateDeclaration;
191 fs <<
"void " << name << defTemplate <<
"::move" << name <<
"(" << name << defTemplate <<
" && other){" << std::endl;
192 fs <<
"\tif(this == &other){return;}" << std::endl;
193 for(std::vector<PClassAttribute>::const_iterator it(listAttr.begin()); it != listAttr.end(); ++it){
195 fs <<
"\tdelete p_" << it->getName() <<
";" << std::endl;
196 fs <<
"\tp_" << it->getName() <<
" = other.p_" << it->getName() <<
";" << std::endl;
197 fs <<
"\tother.p_" << it->getName() <<
" = NULL;" << std::endl;
199 fs <<
"\tp_" << it->getName() <<
" = std::move(other.p_" << it->getName() <<
");" << std::endl;
202 fs <<
"}" << std::endl << std::endl;
213 PString name(classConfig.
getName());
214 fs <<
"namespace " << name <<
" {\n";
216 fs <<
"\tenum " << name <<
" {\n\t\t";
217 const std::vector<PClassAttribute> & vecAttr(classConfig.
getListAttribute());
221 for(std::vector<PClassAttribute>::const_iterator it(vecAttr.begin()); it != vecAttr.end(); ++it){
222 if(it->getDocumentation() !=
"") fs <<
"\t\t" << it->getDocumentation() << std::endl;
223 fs << comma << it->getName();
224 if(isDefaultCounterActivated){
226 }
else if(it->getDefaultValue() !=
""){
227 fs <<
" = " << it->getDefaultValue();
232 fs <<
"\n\t};" << std::endl;
233 fs <<
"}" << std::endl << std::endl;
235 fs << std::endl << std::endl;
247 PString name(classConfig.
getName());
258 if(namespaceName !=
""){
259 fs << namespaceName <<
"::";
264 fs <<
" : public " << *it;
273 fs <<
"{" << std::endl;
274 fs <<
"\tpublic:" << std::endl;
275 fs <<
"\t\t" << name <<
"() = default;" << std::endl;
276 if(hasPointerAttribute){
279 fs <<
"\t\tvirtual ~" << name <<
"();" << std::endl;
280 fs <<
"\t\t" << name <<
"(const " << name <<
" &);" << std::endl;
281 fs <<
"\t\t" << name <<
" & operator = (const " << name <<
" &);" << std::endl;
282 fs <<
"\t\t" << name <<
"(" << name <<
" &&) noexcept;" << std::endl;
283 fs <<
"\t\t" << name <<
" & operator = (" << name <<
" &&) noexcept;" << std::endl;
285 fs <<
"\t\tvirtual ~" << name <<
"() = default;" << std::endl;
287 fs <<
"\t\t" << name <<
"(const " << name <<
" &) = default;" << std::endl;
288 fs <<
"\t\t" << name <<
" & operator = (const " << name <<
" &) = default;" << std::endl;
289 fs <<
"\t\t" << name <<
"(" << name <<
" &&) = default;" << std::endl;
290 fs <<
"\t\t" << name <<
" & operator = (" << name <<
" &&) = default;" << std::endl;
297 std::ostringstream protectedContentBuf;
298 std::ofstream protectedCapture;
301 static_cast<std::ostream &
>(protectedCapture).rdbuf(protectedContentBuf.rdbuf());
303 PString protectedContent(protectedContentBuf.str());
304 if(hasPointerAttribute || protectedContent !=
""){
305 fs <<
"\tprotected:" << std::endl;
306 if(hasPointerAttribute){
307 fs <<
"\t\tvoid copy" << name <<
"(const " << name <<
" & other);" << std::endl;
308 fs <<
"\t\tvoid move" << name <<
"(" << name <<
" && other);" << std::endl;
310 fs << protectedContent;
313 fs <<
"\tprivate:" << std::endl;
315 const std::vector<PClassAttribute> & listAttr(classConfig.
getListAttribute());
316 for(std::vector<PClassAttribute>::const_iterator it(listAttr.begin()); it != listAttr.end(); ++it){
317 if(it->getDocumentation() !=
"") fs <<
"\t\t" << it->getDocumentation() << std::endl;
319 fs <<
"\t\t" << it->getType() <<
" p_" << it->getName() << defaultInit <<
";" << std::endl;
321 fs <<
"};" << std::endl << std::endl;
323 fs << std::endl << std::endl;
336 const PVecPath & vecInclude,
const PString & includeTemplate)
338 if(headerFile ==
"")
return false;
340 if(!openFileStream(fs, headerFile)){
return false;}
343 fs <<
"#ifndef " << macroDef << std::endl;
344 fs <<
"#define " << macroDef << std::endl << std::endl;
345 fs <<
"#include <string>" << std::endl;
346 if(vecInclude.size() != 0LU){
347 for(PVecPath::const_iterator it(vecInclude.begin()); it != vecInclude.end(); ++it){
348 fs <<
"#include " << *it << std::endl;
354 for(std::vector<PClassConfig>::const_iterator it(vecClassConfig.begin()); it != vecClassConfig.end(); ++it){
363 if(includeTemplate !=
""){
364 fs <<
"#include \""<<includeTemplate<<
"\"" << std::endl << std::endl;
367 fs << std::endl << std::endl <<
"#endif" << std::endl << std::endl;
404 const std::vector<PClassConfig> & vecClassConfig,
const GeneratorMode & mode,
bool isTemplateImpl)
406 if(sourceFile ==
"" || headerFile ==
"")
return false;
408 if(!openFileStream(fs, sourceFile)){
return false;}
412 fs <<
"#ifndef " << macroDef << std::endl;
413 fs <<
"#define " << macroDef << std::endl << std::endl;
415 fs << std::endl <<
"#include \"" << headerFile.getFileName() <<
"\"" << std::endl;
416 bool hasPointerAttribute(
false);
417 for(std::vector<PClassConfig>::const_iterator it(vecClassConfig.begin()); it != vecClassConfig.end() && !hasPointerAttribute; ++it){
420 if(hasPointerAttribute){
421 fs <<
"#include <utility>" << std::endl;
424 bool hasNamespace(
false);
425 for(std::vector<PClassConfig>::const_iterator it(vecClassConfig.begin()); it != vecClassConfig.end(); ++it){
426 if(it->getNamespace() !=
"" && !hasNamespace){
427 fs <<
"using namespace " << it->getNamespace() <<
";" << std::endl << std::endl;
431 for(std::vector<PClassConfig>::const_iterator it(vecClassConfig.begin()); it != vecClassConfig.end(); ++it){
435 fs <<
"#endif" << std::endl << std::endl;
452 for(std::vector<PClassConfig>::const_iterator it(vecClassConfig.begin()); it != vecClassConfig.end(); ++it){
453 bool isTemplate = it->getListTemplate().size() != 0LU;
454 hasSource |= !isTemplate;
455 hasTemplate |= isTemplate;
468 if(baseFileName ==
""){
469 std::cerr << termRed() <<
"generator_class_cpp : baseFileName is empty" << termDefault() << std::endl;
472 bool hasSource(
false), hasTemplate(
false);
474 PString includeTemplate(
"");
476 includeTemplate = PString(baseFileName.getFileName() +
"_impl.h");
478 PPath headerFile = outputSourceDir / PPath(baseFileName +
".h");
480 std::cerr << termRed() <<
"generator_class_cpp : cannot generate header file '"<<headerFile<<
"'" << termDefault() << std::endl;
484 PPath sourceFile = outputSourceDir / PPath(baseFileName + PString(
".cpp"));
486 std::cerr << termRed() <<
"generator_class_cpp : cannot generate source file '"<<sourceFile<<
"'" << termDefault() << std::endl;
491 PPath implFile = outputSourceDir / PPath(baseFileName + PString(
"_impl.h"));
493 std::cerr << termRed() <<
"generator_class_cpp : cannot generate impl file '"<<implFile<<
"'" << termDefault() << std::endl;
511 if(!openFileStream(fs, PPath(outputCurrentTestDir + PString(
"/main.cpp")))){
return false;}
517 fs <<
"#include \"" + baseFileName +
".h\"\n\n";
520 fs <<
"int main(int argc, char ** argv){\n";
523 fs <<
"\treturn 0;\n";
537 PString body(
""), testName(
"test_class_" + classConfig.
getName().toLowerUnderscore());
539 body +=
"add_executable("+testName+
" main.cpp)\n";
540 body +=
"target_link_libraries("+testName+
" ${"+projectName.toUpper()+
"_TEST_DEPENDENCIES})\n";
542 body +=
"add_test(NAME "+testName.firstToUpper()+
"\n";
543 body +=
"\tCOMMAND ${CMAKE_CURRENT_BINARY_DIR}/"+testName+
"\n";
544 body +=
"\tWORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}\n";
546 return PPath(outputCurrentTestDir + PString(
"/CMakeLists.txt")).saveFileContent(body);
559 PString name(classConfig.
getName());
560 PPath outputCurrentTestDir(outputTestDir + PString(
"/TEST_") + name.toUpper());
561 if(!outputCurrentTestDir.createDirectory()){std::cerr <<
"generator_class_test : cannot create TEST directory '"<<outputCurrentTestDir<<
"'" << std::endl;
return false;}
579 PString cmakeListBody;
582 cmakeListBody +=
"#Generating tests for " + PString::toString(vecClassConfig.size()) +
"\n";
583 for(std::vector<PClassConfig>::const_iterator it(vecClassConfig.begin()); it != vecClassConfig.end(); ++it){
584 cmakeListBody +=
"add_subdirectory(TEST_" + it->getName().toUpper() +
")\n";
587 cmakeListBody +=
"\n\n";
588 PPath cmakelist(outputTestDir / PPath(
"CMakeLists.txt"));
589 b &= cmakelist.saveFileContent(cmakeListBody);
602 PString cmakeListBody;
606 PPath baseFileName = config.getFileName().getFileName().eraseExtension();
608 std::cerr << termRed() <<
"generator_class_full : cannot generate C++ sources at '"<<projectParam.
outputSourceDir<<
"'" << termDefault() << std::endl;
611 PPath outputCurrentTestDir = projectParam.
outputTestDir / PPath(
"TEST_" + config.getFileName().getFileName().eraseExtension().toUpper());
612 cmakeListBody +=
"add_subdirectory(" + outputCurrentTestDir.getFileName() +
")\n";
614 std::cerr << termRed() <<
"generator_class_full : cannot generate C++ tests at '"<<projectParam.
outputTestDir<<
"'" << termDefault() << std::endl;
618 cmakeListBody +=
"\n\n";
619 PPath cmakelist(projectParam.
outputTestDir / PPath(
"CMakeLists.txt"));
620 b &= cmakelist.saveFileContent(cmakeListBody);
std::vector< PDataConfig > PVecDataConfig
Describes a class attribute.
const PString & getDefaultValue() const
Gets the defaultValue of the PClassAttribute.
const PString & getType() const
Gets the type of the PClassAttribute.
Class to describe a basic class.
const PString & getClassDocumentation() const
Returns the class documentation.
const std::vector< PClassAttribute > & getListAttribute() const
Returns the list of attributes of the class.
const PVecString & getListTemplate() const
Returns the list of the template of the class.
const PString & getName() const
Returns the class name.
bool getIsEnum() const
Say if the current PClassConfig is an enum.
const PVecString & getListParentClass() const
Returns the list of the parents of the class.
const PString & getNamespace() const
Returns the namespace of the class.
Class to describe a basic class.
Manager of the Trait backends.
void protectedMethodDeclaration(std::ofstream &fs, const PClassConfig &classConfig, const GeneratorMode &mode) const
Declaration of protected methods.
void classExtraFunctionDeclaration(std::ofstream &fs, const PClassConfig &classConfig, const GeneratorMode &mode) const
Declaration of extra functions.
void testCallFunction(std::ofstream &fs, const PClassConfig &classConfig, const GeneratorMode &mode) const
Call of the test function.
void classExtraFunctionImplementation(std::ofstream &fs, const PClassConfig &classConfig, const GeneratorMode &mode) const
Implementation of extra functions.
void headerExtraInclude(std::ofstream &fs, const GeneratorMode &mode) const
Add extra include on the header.
void privateMethodDeclaration(std::ofstream &fs, const PClassConfig &classConfig, const GeneratorMode &mode) const
Declaration of private methods.
void protectedMethodImplementation(std::ofstream &fs, const PClassConfig &classConfig, const GeneratorMode &mode) const
Implementation of protected methods.
void privateMethodImplementation(std::ofstream &fs, const PClassConfig &classConfig, const GeneratorMode &mode) const
Implementation of private methods.
void publicMethodImplementation(std::ofstream &fs, const PClassConfig &classConfig, const GeneratorMode &mode) const
Implementation of public methods.
void publicMethodDeclaration(std::ofstream &fs, const PClassConfig &classConfig, const GeneratorMode &mode) const
Declaration of public methods.
void testFunction(std::ofstream &fs, const PClassConfig &classConfig, const GeneratorMode &mode) const
Implementation of test function.
PString getCMakeListsHeader()
Get the CMakeLists.txt header.
void class_savePointerOwnershipSpecialMembersImpl(std::ofstream &fs, const PClassConfig &classConfig, const PString &defTemplate, const PString &templateDeclaration)
Saves the destructor, copy constructor/assignment and move constructor/assignment of a class owning a...
bool generator_checkDefaultValueExist(const std::vector< PClassAttribute > &vecAttr)
Check if the vector of PClassAttribute has default value.
PString class_getClassDefTemplate(const PVecString &listTemplate)
Get the template call in the class declaration.
void generator_class_cpp_source(const PTraitBackendManager &manager, std::ofstream &fs, const PClassConfig &classConfig, const GeneratorMode &mode)
Create the implementation of the given class.
PString class_getAttributeDefaultInit(const PClassAttribute &attr)
Get the in-class default member initialiser of an attribute (eg "{0}"), or an empty PString if the at...
void generator_class_cpp_header(const PTraitBackendManager &manager, std::ofstream &fs, const PClassConfig &classConfig, const GeneratorMode &mode)
Create the declaration of the given class.
bool generator_class_cpp(const PTraitBackendManager &manager, const std::vector< PClassConfig > &vecClassConfig, const PPath &outputSourceDir, const PPath &baseFileName, const GeneratorMode &mode, const PVecPath &vecInclude)
Creates header and source files.
PString class_getClassDeclTempalteDef(const PVecString &listTemplate)
Get the template definition in the class declaration.
bool generator_class_test(const PTraitBackendManager &manager, const PPath &outputTestDir, const PClassConfig &classConfig, const PString &projectName, const PPath &baseFileName, const GeneratorMode &mode)
Save the unit test of the generated PClassConfig.
bool generator_class_cpp_sourceFile(const PTraitBackendManager &manager, const PPath &sourceFile, const PPath &headerFile, const std::vector< PClassConfig > &vecClassConfig, const GeneratorMode &mode, bool isTemplateImpl)
Create the implementation of the given file.
bool generator_class_cpp_test(const PTraitBackendManager &manager, const PPath &outputTestDir, const std::vector< PClassConfig > &vecClassConfig, const PString &projectName, const PPath &baseFileName, const GeneratorMode &mode)
Save the unit test of the generated PClassConfig.
void class_checkClassConfig(bool &hasSource, bool &hasTemplate, const std::vector< PClassConfig > &vecClassConfig)
Check if the configuration has source or template to determine if the .cpp or _impl....
bool generator_class_full(const PTraitBackendManager &manager, const ProjectParam &projectParam)
Generate the full sources and related unit tests from configuration.
bool generator_class_cpp_headerFile(const PTraitBackendManager &manager, const PPath &headerFile, const std::vector< PClassConfig > &vecClassConfig, const GeneratorMode &mode, const PVecPath &vecInclude, const PString &includeTemplate)
Create the declaration of the given class.
bool generator_class_testMain(const PTraitBackendManager &manager, const PPath &outputCurrentTestDir, const PClassConfig &classConfig, const PPath &baseFileName, const GeneratorMode &mode)
Save the CMakeLists to be used to compile the unit test.
void generator_enum_cpp_header(const PTraitBackendManager &manager, std::ofstream &fs, const PClassConfig &classConfig, const GeneratorMode &mode)
Create the declaration of the given class.
bool generator_class_testCMakeLists(const PPath &outputCurrentTestDir, const PClassConfig &classConfig, const PString &projectName, const GeneratorMode &mode)
Save the CMakeLists to be used to compile the unit test.
bool class_hasPointerAttribute(const PClassConfig &classConfig)
Check if the given class owns at least one pointer attribute.
PString defTemplate
Template definition for the class header.
PString assertInclude
Include of the assert to be used.
PString templateDeclaration
Template declaration of the method implementation.
Set of parameters to generate a project.
GeneratorMode mode
Mode to be used to generate the project.
PPath outputTestDir
Output path of the unit tests.
PVecDataConfig vecDataConfig
Configuration of classes to be generated.
PString name
Name of the project.
PPath outputSourceDir
Output path of the sources.
bool getIsPointerType(const PString &varType)
Say if a given type is a pointer type (i.e. it ends with a '*').
PString getDefaultValueTypeInCpp(const PString &type)
Get the default value of a type in C++.