PhoenixGenerator  2.8.0
Set of tools to generate code
Loading...
Searching...
No Matches
nanobind_generator.cpp
Go to the documentation of this file.
1/***************************************
2 Auteur : Thibaut Oprinsen, Pierre Aubert
3 Mail : thibaut.oprinsen@lapp.in2p3.fr, pierre.aubert@lapp.in2p3.fr
4 Licence : CeCILL-C
5****************************************/
6
7#include <set>
8#include "header_generator.h"
10#include "phoenix_color.h"
11#include "openFileStream.h"
12
14
23bool generator_nanobind_class(const PNanobindTraitBackendManager &manager, PPath& baseFileName, const PPath &sourceFile, const PPath &headerFile, const PVecPath &extraInclude, const PVecClassConfig &vecClassConfig, const GeneratorMode &mode){
24 if(baseFileName == ""){
25 std::cerr << termRed() << "generator_class_cpp : baseFileName is empty" << termDefault() << std::endl;
26 return false;
27 }
28 std::ofstream fs;
29 if(!openFileStream(fs, sourceFile)){return false;}
30 licenceSave(fs);
31 fs << std::endl << "#include \"" << headerFile.getFileName() << "\"" << std::endl << std::endl;
32 fs << "#include <nanobind/nanobind.h>" << std::endl;
33 std::set<std::string> extraIncludes;
34 for (std::vector<PClassConfig>::const_iterator it(vecClassConfig.begin()); it != vecClassConfig.end(); ++it){
35 manager.headerExtraInclude(extraIncludes, *it, mode);
36 }
37 for (const std::string & include : extraIncludes){
38 fs << include << std::endl;
39 }
40 fs << "\nnamespace nb = nanobind;" << std::endl << std::endl;
41 PString fileModuleName = baseFileName.toLower();
42 fs << "NB_MODULE(" << fileModuleName << ", m) {" << std::endl;
43 fs << "\tm.doc() = \"Nanobind bindings for " << baseFileName << " classes\";\n" << std::endl;
44
45 for(std::vector<PClassConfig>::const_iterator it(vecClassConfig.begin()); it != vecClassConfig.end(); ++it){
46 if(it->getIsEnum()){
47 fs << "\tnb::enum_<" << it->getName() << "::" << it->getName() << ">(m, \"" << it->getName() << "\")" << std::endl;
48 fs << "\t\t//Values" << std::endl;
49 manager.registerProperty(fs, *it, mode);
50 manager.registerStaticMethod(fs, *it, mode);
51 manager.registerMethod(fs, *it, mode);
52 fs << ";" << std::endl << std::endl;
53 }else{
54 fs << "\tnb::class_<" << it->getName() << ">(m, \"" << it->getName() << "\")" << std::endl;
55 fs << "\t\t//Attributes" << std::endl;
56 manager.registerProperty(fs, *it, mode);
57 manager.registerConstructor(fs, *it, mode);
58 manager.registerStaticMethod(fs, *it, mode);
59
60 manager.registerMethod(fs, *it, mode);
61 fs << ";" << std::endl << std::endl;
62 }
63 }
64 fs << "}" << std::endl; // Close NB_MODULE
65 fs.close();
66 return true;
67}
68
70
78bool generator_nanobind_test(const PNanobindTraitBackendManager & manager, const PPath & outputTestDir, const std::vector<PClassConfig> & vecClassConfig, const PString & projectName, const PPath & baseFileName, const GeneratorMode & mode){
79 for(std::vector<PClassConfig>::const_iterator it(vecClassConfig.begin()); it != vecClassConfig.end(); ++it){
80 PString name = it->getName();
81 PPath outputCurrentTestDir(outputTestDir + PString("/TEST_") + name.toUpper() + "_BINDINGS");
82 if(!outputCurrentTestDir.createDirectory()){
83 std::cerr << "generator_class_test : cannot create TEST directory '"<<outputCurrentTestDir<<"'" << std::endl;
84 return false;
85 }
86 std::ofstream fs;
87 if(!openFileStream(fs, PPath(outputCurrentTestDir + PString("/test_") + name + "_binding.py"))){return false;}
88 manager.headerTestInclude(fs, mode, baseFileName);
89 manager.testFunction(fs, *it, mode, baseFileName);
90 fs.close();
91 }
92 return true;
93}
94
96
100bool generator_nanobind_full(const PNanobindTraitBackendManager & manager, const ProjectParam & projectParam)
101{
102 bool b(true);
103 b &= projectParam.outputSourceDir.createDirectory();
104 b &= projectParam.outputTestDir.createDirectory();
105 const PVecDataConfig & vecDataConfig = projectParam.vecDataConfig;
106
107 for(const PDataConfig & config : vecDataConfig){
108 const PVecPath & extraInclude = config.getVecInclude();
109 PPath baseFileName = config.getFileName().getFileName().eraseExtension();
110 PPath headerFile = projectParam.outputSourceDir / PPath(baseFileName + ".h");
111 PPath sourceFile = projectParam.outputSourceDir / PPath(baseFileName + "_binding.cpp");
112 if(!generator_nanobind_class(manager, baseFileName, sourceFile, headerFile, extraInclude, config.getVecClassConfig(), projectParam.mode)){
113 std::cerr << termRed() << "generator_nanobind_full : cannot generate nanobind sources at '"<<projectParam.outputSourceDir<<"'" << termDefault() << std::endl;
114 b = false; //best effort strategy
115 }
116 PPath outputCurrentTestDir = projectParam.outputTestDir / PPath("TEST_PYTHON_BINDINGS");
117 if(!generator_nanobind_test(manager, outputCurrentTestDir, config.getVecClassConfig(), projectParam.name, baseFileName, projectParam.mode)){
118 std::cerr << termRed() << "generator_nanobind_full : cannot generate nanobind tests at '"<<projectParam.outputTestDir<<"'" << termDefault() << std::endl;
119 b = false; //best effort strategy
120 }
121 }
122 return b;
123}
std::vector< PDataConfig > PVecDataConfig
Definition PDataConfig.h:48
std::vector< PClassConfig > PVecClassConfig
Definition PDataConfig.h:14
Class to describe a basic class.
Definition PDataConfig.h:17
Manager of the Trait backends.
virtual void headerTestInclude(std::ofstream &fs, const GeneratorMode &mode, const PString &baseFileName) const
Add extra include on the test header.
virtual void registerStaticMethod(std::ofstream &fs, const PClassConfig &classConfig, const GeneratorMode &mode) const
Registration of static method.
virtual void headerExtraInclude(std::set< std::string > &setInclude, const PClassConfig &classConfig, const GeneratorMode &mode) const
Add extra include on the header.
virtual void registerProperty(std::ofstream &fs, const PClassConfig &classConfig, const GeneratorMode &mode) const
Registration of property.
virtual void testFunction(std::ofstream &fs, const PClassConfig &classConfig, const GeneratorMode &mode, const PString &baseFileName) const
Implementation of test function.
virtual void registerMethod(std::ofstream &fs, const PClassConfig &classConfig, const GeneratorMode &mode) const
Registration of method.
virtual void registerConstructor(std::ofstream &fs, const PClassConfig &classConfig, const GeneratorMode &mode) const
Registration of constructor.
void licenceSave(std::ofstream &fs)
Saves the policy.
bool generator_nanobind_test(const PNanobindTraitBackendManager &manager, const PPath &outputTestDir, const std::vector< PClassConfig > &vecClassConfig, const PString &projectName, const PPath &baseFileName, const GeneratorMode &mode)
Generate test with nanobind.
bool generator_nanobind_full(const PNanobindTraitBackendManager &manager, const ProjectParam &projectParam)
Generate the full sources and related unit tests from configuration.
bool generator_nanobind_class(const PNanobindTraitBackendManager &manager, PPath &baseFileName, const PPath &sourceFile, const PPath &headerFile, const PVecPath &extraInclude, const PVecClassConfig &vecClassConfig, const GeneratorMode &mode)
Generate nanobind wrapper class.
All the genertor modes.
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.