PhoenixGenerator  3.4.0
Generate code from template files and projects in C++, Rust, Python and wrapped C++ to Python
Loading...
Searching...
No Matches
generator_class_cpp.h File Reference
#include "ProjectParam.h"
Include dependency graph for generator_class_cpp.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

PString class_getClassDefTemplate (const PVecString &listTemplate)
 Get the template call in the class declaration.
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.
void generator_class_cpp_header (const PTraitBackendManager &manager, std::ofstream &fs, const PClassConfig &classConfig, const GeneratorMode &mode)
 Create the declaration of the given class.
void generator_class_cpp_source (const PTraitBackendManager &manager, std::ofstream &fs, const PClassConfig &classConfig, const GeneratorMode &mode)
 Create the implementation of the given class.
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.
bool generator_class_full (const PTraitBackendManager &manager, const ProjectParam &projectParam)
 Generate the full sources and related unit tests from configuration.

Function Documentation

◆ class_getClassDefTemplate()

PString class_getClassDefTemplate ( const PVecString & listTemplate)

Get the template call in the class declaration.

Parameters
listTemplate: list of template def
Returns
template definition in the class declaration (< T, U, .... >)

Definition at line 31 of file generator_class_cpp.cpp.

31 {
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();
38 comma = ", ";
39 }
40 }
41 defTemplate += ">";
42 return defTemplate;
43}

References class_getClassDefTemplate().

Referenced by class_getClassDefTemplate(), generator_class_cpp_header(), and generator_class_cpp_source().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ generator_class_cpp()

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.

Parameters
manager: PTraitBackendManager which handles all trait backend
vecClassConfig: vector of class config we want to save
baseFileName: base file name for header or source file
outputSourceDir: output directory where to save sources
mode: all modes of the generator (data/check/type/config stream)
Returns
true on success, false otherwise

Definition at line 467 of file generator_class_cpp.cpp.

467 {
468 if(baseFileName == ""){
469 std::cerr << termRed() << "generator_class_cpp : baseFileName is empty" << termDefault() << std::endl;
470 return false;
471 }
472 bool hasSource(false), hasTemplate(false);
473 class_checkClassConfig(hasSource, hasTemplate, vecClassConfig);
474 PString includeTemplate("");
475 if(hasTemplate){
476 includeTemplate = PString(baseFileName.getFileName() + "_impl.h");
477 }
478 PPath headerFile = outputSourceDir / PPath(baseFileName + ".h");
479 if(!generator_class_cpp_headerFile(manager, headerFile, vecClassConfig, mode, vecInclude, includeTemplate)){
480 std::cerr << termRed() << "generator_class_cpp : cannot generate header file '"<<headerFile<<"'" << termDefault() << std::endl;
481 return false;
482 }
483 if(hasSource){
484 PPath sourceFile = outputSourceDir / PPath(baseFileName + PString(".cpp"));
485 if(!generator_class_cpp_sourceFile(manager, sourceFile, PPath(baseFileName + PString(".h")), vecClassConfig, mode, false)){
486 std::cerr << termRed() << "generator_class_cpp : cannot generate source file '"<<sourceFile<<"'" << termDefault() << std::endl;
487 return false;
488 }
489 }
490 if(hasTemplate){
491 PPath implFile = outputSourceDir / PPath(baseFileName + PString("_impl.h"));
492 if(!generator_class_cpp_sourceFile(manager, implFile, PPath(baseFileName + PString(".h")), vecClassConfig, mode, true)){
493 std::cerr << termRed() << "generator_class_cpp : cannot generate impl file '"<<implFile<<"'" << termDefault() << std::endl;
494 return false;
495 }
496 }
497 return true;
498}
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.
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_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.

References class_checkClassConfig(), generator_class_cpp(), generator_class_cpp_headerFile(), and generator_class_cpp_sourceFile().

Referenced by generator_class_cpp(), and generator_class_full().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ generator_class_cpp_header()

void generator_class_cpp_header ( const PTraitBackendManager & manager,
std::ofstream & fs,
const PClassConfig & classConfig,
const GeneratorMode & mode )

Create the declaration of the given class.

Parameters
manager: PTraitBackendManager which handles all trait backend
[out]fs: file to be completed
classConfig: configuration of the class to be used
mode: mode of the generator

Definition at line 245 of file generator_class_cpp.cpp.

245 {
246 if(classConfig.getClassDocumentation() != "") fs << classConfig.getClassDocumentation() << std::endl;
247 PString name(classConfig.getName());
248 PString namespaceName(classConfig.getNamespace());
249 GeneratorMode classMode(mode);
250 const PVecString & listTemplate = classConfig.getListTemplate();
251 PString defTemplate(class_getClassDefTemplate(listTemplate));
252 PString templateDeclaration(class_getClassDeclTempalteDef(listTemplate));
253 classMode.defTemplate = defTemplate;
254 classMode.templateDeclaration = templateDeclaration;
255
256 fs << classMode.templateDeclaration;
257 fs << "class ";
258 if(namespaceName != ""){
259 fs << namespaceName << "::";
260 }
261 fs << name;
262 if(classConfig.getListParentClass().size() != 0LU){
263 PVecString::const_iterator it(classConfig.getListParentClass().begin());
264 fs << " : public " << *it;
265 if(classConfig.getListParentClass().size() > 1lu){
266 while(it != classConfig.getListParentClass().end()){
267 fs << ", " << *it;
268 ++it;
269 }
270 }
271 }
272 bool hasPointerAttribute(class_hasPointerAttribute(classConfig));
273 fs << "{" << std::endl;
274 fs << "\tpublic:" << std::endl;
275 fs << "\t\t" << name << "() = default;" << std::endl;
276 if(hasPointerAttribute){
277 //A raw pointer attribute cannot be safely copied/moved by the compiler-generated special members (shallow copy/move would double-delete) :
278 //DataStream has no shared_ptr/unique_ptr specialisation, so ownership is a raw pointer and all five special members must be hand-written (rule of five).
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;
284 }else{
285 fs << "\t\tvirtual ~" << name << "() = default;" << std::endl;
286 //A user-declared destructor suppresses the implicitly-declared copy/move constructor and assignment : redeclare all four as defaulted.
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;
291 }
292
293 manager.publicMethodDeclaration(fs, classConfig, classMode);
294
295 //Trait backends write to an std::ofstream& : capture their output into a string buffer first (via a buffer swap, no actual file involved)
296 //so the "protected:" label is only emitted when there is something to put under it, instead of leaving an empty access-specifier section.
297 std::ostringstream protectedContentBuf;
298 std::ofstream protectedCapture;
299 //basic_ofstream declares its own 0-arg rdbuf() (returning the internal filebuf), which hides the inherited basic_ios::rdbuf(streambuf*) setter :
300 //go through the std::ostream base to reach the setter and redirect writes into a string buffer without opening any file.
301 static_cast<std::ostream &>(protectedCapture).rdbuf(protectedContentBuf.rdbuf());
302 manager.protectedMethodDeclaration(protectedCapture, classConfig, classMode);
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;
309 }
310 fs << protectedContent;
311 }
312
313 fs << "\tprivate:" << std::endl;
314 manager.privateMethodDeclaration(fs, classConfig, classMode);
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;
318 PString defaultInit(class_getAttributeDefaultInit(*it));
319 fs << "\t\t" << it->getType() << " p_" << it->getName() << defaultInit << ";" << std::endl;
320 }
321 fs << "};" << std::endl << std::endl;
322 manager.classExtraFunctionDeclaration(fs, classConfig, classMode);
323 fs << std::endl << std::endl;
324}
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.
const PVecString & getListParentClass() const
Returns the list of the parents of the class.
const PString & getNamespace() const
Returns the namespace of the class.
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 privateMethodDeclaration(std::ofstream &fs, const PClassConfig &classConfig, const GeneratorMode &mode) const
Declaration of private methods.
void publicMethodDeclaration(std::ofstream &fs, const PClassConfig &classConfig, const GeneratorMode &mode) const
Declaration of public methods.
PString class_getClassDefTemplate(const PVecString &listTemplate)
Get the template call in the class declaration.
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...
PString class_getClassDeclTempalteDef(const PVecString &listTemplate)
Get the template definition in the class declaration.
bool class_hasPointerAttribute(const PClassConfig &classConfig)
Check if the given class owns at least one pointer attribute.
All the genertor modes.

References class_getAttributeDefaultInit(), class_getClassDeclTempalteDef(), class_getClassDefTemplate(), class_hasPointerAttribute(), PTraitBackendManager::classExtraFunctionDeclaration(), GeneratorMode::defTemplate, generator_class_cpp_header(), PClassConfig::getClassDocumentation(), PClassConfig::getListAttribute(), PClassConfig::getListParentClass(), PClassConfig::getListTemplate(), PClassConfig::getName(), PClassConfig::getNamespace(), PTraitBackendManager::privateMethodDeclaration(), PTraitBackendManager::protectedMethodDeclaration(), PTraitBackendManager::publicMethodDeclaration(), and GeneratorMode::templateDeclaration.

Referenced by generator_class_cpp_header(), and generator_class_cpp_headerFile().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ generator_class_cpp_source()

void generator_class_cpp_source ( const PTraitBackendManager & manager,
std::ofstream & fs,
const PClassConfig & classConfig,
const GeneratorMode & mode )

Create the implementation of the given class.

Parameters
manager: PTraitBackendManager which handles all trait backend
[out]fs: file to be completed
classConfig: configuration of the class to be used
mode: mode of the generator

Definition at line 378 of file generator_class_cpp.cpp.

378 {
379 manager.classExtraFunctionImplementation(fs, classConfig, mode);
380 GeneratorMode classMode(mode);
381 const PVecString & listTemplate = classConfig.getListTemplate();
382 PString defTemplate(class_getClassDefTemplate(listTemplate));
383 PString templateDeclaration(class_getClassDeclTempalteDef(listTemplate));
384 classMode.defTemplate = defTemplate;
385 classMode.templateDeclaration = templateDeclaration;
386 if(!classConfig.getIsEnum()){
387 class_savePointerOwnershipSpecialMembersImpl(fs, classConfig, defTemplate, templateDeclaration);
388 }
389 manager.publicMethodImplementation(fs, classConfig, classMode);
390 manager.protectedMethodImplementation(fs, classConfig, classMode);
391 manager.privateMethodImplementation(fs, classConfig, classMode);
392}
bool getIsEnum() const
Say if the current PClassConfig is an enum.
void classExtraFunctionImplementation(std::ofstream &fs, const PClassConfig &classConfig, const GeneratorMode &mode) const
Implementation of extra functions.
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 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...

References class_getClassDeclTempalteDef(), class_getClassDefTemplate(), class_savePointerOwnershipSpecialMembersImpl(), PTraitBackendManager::classExtraFunctionImplementation(), GeneratorMode::defTemplate, generator_class_cpp_source(), PClassConfig::getIsEnum(), PClassConfig::getListTemplate(), PTraitBackendManager::privateMethodImplementation(), PTraitBackendManager::protectedMethodImplementation(), PTraitBackendManager::publicMethodImplementation(), and GeneratorMode::templateDeclaration.

Referenced by generator_class_cpp_source(), and generator_class_cpp_sourceFile().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ generator_class_cpp_test()

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.

Parameters
manager: PTraitBackendManager which handles all trait backend
outputTestDir: output directory where to put the generated test (typically ../TESTS if the program is called from ./src)
vecClassConfig: vector of class configuration to be used
projectName: configuration of the project
baseFileName: base of output file name of the generated sources
mode: all modes of the generator (data/check/type/config stream)
Returns
true on success, false oterhwise

Definition at line 578 of file generator_class_cpp.cpp.

578 {
579 PString cmakeListBody;
580 cmakeListBody += getCMakeListsHeader();
581 bool b(true);
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";
585 b &= generator_class_test(manager, outputTestDir, *it, projectName, baseFileName, mode);
586 }
587 cmakeListBody += "\n\n";
588 PPath cmakelist(outputTestDir / PPath("CMakeLists.txt"));
589 b &= cmakelist.saveFileContent(cmakeListBody);
590 return b;
591}
PString getCMakeListsHeader()
Get the CMakeLists.txt header.
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.

References generator_class_cpp_test(), generator_class_test(), and getCMakeListsHeader().

Referenced by generator_class_cpp_test(), and generator_class_full().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ generator_class_full()

bool generator_class_full ( const PTraitBackendManager & manager,
const ProjectParam & projectParam )

Generate the full sources and related unit tests from configuration.

Parameters
manager: PTraitBackendManager which handles all trait backend
projectParam: description of classes and how and where to generate sources and test
Returns
true on success, false otherwise

Definition at line 598 of file generator_class_cpp.cpp.

598 {
599 bool b(true);
600 b &= projectParam.outputSourceDir.createDirectory();
601 b &= projectParam.outputTestDir.createDirectory();
602 PString cmakeListBody;
603 cmakeListBody += getCMakeListsHeader();
604 const PVecDataConfig & vecDataConfig = projectParam.vecDataConfig;
605 for(const PDataConfig & config : vecDataConfig){
606 PPath baseFileName = config.getFileName().getFileName().eraseExtension();
607 if(!generator_class_cpp(manager, config.getVecClassConfig(), projectParam.outputSourceDir, baseFileName, projectParam.mode, config.getVecInclude())){
608 std::cerr << termRed() << "generator_class_full : cannot generate C++ sources at '"<<projectParam.outputSourceDir<<"'" << termDefault() << std::endl;
609 b = false; //best effort strategy
610 }
611 PPath outputCurrentTestDir = projectParam.outputTestDir / PPath("TEST_" + config.getFileName().getFileName().eraseExtension().toUpper());
612 cmakeListBody += "add_subdirectory(" + outputCurrentTestDir.getFileName() + ")\n";
613 if(!generator_class_cpp_test(manager, outputCurrentTestDir, config.getVecClassConfig(), projectParam.name, baseFileName, projectParam.mode)){
614 std::cerr << termRed() << "generator_class_full : cannot generate C++ tests at '"<<projectParam.outputTestDir<<"'" << termDefault() << std::endl;
615 b = false; //best effort strategy
616 }
617 }
618 cmakeListBody += "\n\n";
619 PPath cmakelist(projectParam.outputTestDir / PPath("CMakeLists.txt"));
620 b &= cmakelist.saveFileContent(cmakeListBody);
621 return b;
622}
std::vector< PDataConfig > PVecDataConfig
Definition PDataConfig.h:48
Class to describe a basic class.
Definition PDataConfig.h:17
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.
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.
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.

References generator_class_cpp(), generator_class_cpp_test(), generator_class_full(), getCMakeListsHeader(), ProjectParam::mode, ProjectParam::name, ProjectParam::outputSourceDir, ProjectParam::outputTestDir, and ProjectParam::vecDataConfig.

Referenced by generateCppClassesFull(), and generator_class_full().

Here is the call graph for this function:
Here is the caller graph for this function: