Added GPLv3 headers all over the place.
[fail.git] / src / core / failit / method.cpp
blobafb8c936a8ca09abf626f08cbac2be0caa378d37
1 /*
2 Fail game engine
3 Copyright 2007 Antoine Chavasse <a.chavasse@gmail.com>
5 This file is part of Fail.
7 Fail is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License version 3
9 as published by the Free Software Foundation.
11 Fail is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include <ostream>
20 #include <sstream>
21 #include "core/idlast/namespace.h"
22 #include "method.h"
23 #include "type.h"
24 #include "flags.h"
26 using namespace fail::failit;
27 using namespace std;
29 namespace
31 using namespace fail;
32 void GenerateFunctionTraits( std::ostream& Out_,
33 const idlast::Overloads& Overloads_,
34 bool bStatic_,
35 const char* pName_,
36 bool bStruct_ );
38 int GenerateParamNumOverloadResolver( std::ostream& Out_,
39 const idlast::Overloads& Overloads_,
40 std::string Indent_,
41 int OvlId_ );
43 int GenerateTypeOverloadResolver( std::ostream& Out_,
44 const idlast::Overloads& Overloads_,
45 std::string Indent_,
46 int OvlId_ );
49 void fail::failit::GenerateMethodTraits( std::ostream& Out_,
50 const idlast::Class* pClass_,
51 const idlast::Method* pMtd_,
52 bool bStatic_ )
54 string FullClassName( pClass_->getName() );
55 const idlast::Namespace* pCurrentNS = pClass_->getNamespace();
56 while( pCurrentNS->getParent() )
58 FullClassName = pCurrentNS->getName() + "::" + FullClassName;
59 pCurrentNS = pCurrentNS->getParent();
62 Out_ << '\n';
63 std::stringstream tagstring;
64 tagstring << "class_traits< " << FullClassName << " >::";
66 if( bStatic_ )
67 tagstring << "static_";
69 tagstring << "method_tags::" << pMtd_->getName();
70 OutputFlags( Out_, pMtd_->getFlags(), tagstring.str() );
72 Out_ << "\ttemplate< class C > struct method_traits< C,\n"
73 "\t\t" << tagstring.str() << " >\n"
74 "\t{\n"
75 "\t\tstatic const char* Name() { return \"" << pMtd_->getName() << "\"; }\n";
77 GenerateFunctionTraits( Out_, pMtd_->getOverloads(), bStatic_, pMtd_->getName().c_str(), false );
79 Out_ << "\t};\n";
82 void fail::failit::GenerateCtorTraits( std::ostream& Out_,
83 const idlast::Class* pClass_,
84 bool bStruct_ )
86 string FullClassName( pClass_->getName() );
87 const idlast::Namespace* pCurrentNS = pClass_->getNamespace();
88 while( pCurrentNS->getParent() )
90 FullClassName = pCurrentNS->getName() + "::" + FullClassName;
91 pCurrentNS = pCurrentNS->getParent();
94 Out_ << '\n';
95 std::stringstream tagstring;
96 tagstring << "class_traits< " << FullClassName << " >::ctor_tag";
97 OutputFlags( Out_, pClass_->getCtorFlags(), tagstring.str() );
99 Out_ << "\ttemplate< class C > struct method_traits< C,\n"
100 "\t\t" << tagstring.str() << " >\n"
101 "\t{\n"
102 "\t\tstatic const char* Name() { return \"ctor_\"; }\n";;
104 GenerateFunctionTraits( Out_, pClass_->getConstructors(), false, NULL, bStruct_ );
106 Out_ << "\t};\n";
109 namespace
112 void GenerateFunctionTraits( std::ostream& Out_,
113 const idlast::Overloads& Overloads_,
114 bool bStatic_,
115 const char* pName_,
116 bool bStruct_ )
118 idlast::Overloads::const_iterator ovit;
119 int ovlcount = 0;
120 int numoverloads = Overloads_.size();
122 for( ovit = Overloads_.begin(); ovit != Overloads_.end(); ++ovit )
124 Out_ << "\n\t\ttemplate< class CC > struct ";
126 if( numoverloads == 1 )
127 Out_ << "CallWrapper";
128 else
129 Out_ << "Overload" << ovlcount;
131 Out_ << "\n"
132 "\t\t{\n"
133 "\t\t\tstatic bool Call( CC& CallContext_ )\n"
134 "\t\t\t{\n";
136 if( !bStatic_ && pName_ )
137 Out_ << "\t\t\t\tC& Obj = CallContext_.getObject();\n";
138 Out_ << "\t\t\t\tCallContext_.numExpectedParams( " << ovit->first << " );\n";
140 const idlast::ParamList& Params = *ovit->second;
141 idlast::ParamList::const_iterator paramit;
142 for( paramit = Params.begin(); paramit != Params.end(); ++paramit )
144 Out_ << "\n\t\t\t\t";
145 PrintType( Out_, paramit->second );
146 Out_ << ' ' << paramit->first << ";\n"
147 "\t\t\t\tif( !CallContext_.template getParam< ";
149 PrintTypeCategory( Out_, paramit->second );
151 Out_ << " >( \"" << paramit->first
152 << "\", " << paramit->first << " ) ) return false;\n";
155 if( !Params.empty() )
156 Out_ << '\n';
158 Out_ << "\t\t\t\t";
160 if( !pName_ )
161 // No name: this is a constructor.
162 Out_ << "CallContext_.template constructObject(";
163 else
165 // Plain method call, with or without a return value...
166 if( Params.getReturnType() )
168 Out_ << "CallContext_.template setReturnValue\n"
169 "\t\t\t\t\t< ";
170 PrintTypeCategory( Out_, Params.getReturnType() );
171 Out_ << ", ";
172 PrintType( Out_, Params.getReturnType() );
173 Out_ << " >\n"
174 "\t\t\t\t\t( ";
177 // And either static or not.
178 if( bStatic_ )
179 Out_ << "C::";
180 else
181 Out_ << "Obj.";
183 Out_ << pName_ << '(';
186 for( paramit = Params.begin(); paramit != Params.end(); ++paramit )
188 if( paramit != Params.begin() )
189 Out_ << ',';
190 Out_ << ' ' << paramit->first;
193 if( !Params.empty() )
194 Out_ << ' ';
196 Out_ << ')';
198 if( pName_ && Params.getReturnType() )
199 Out_ << " )";
201 Out_ << ";\n"
202 "\t\t\t\treturn true;\n"
203 "\t\t\t}\n"
204 "\t\t};\n";
205 ++ovlcount;
208 if( numoverloads > 1 )
210 Out_ << "\n\t\ttemplate< class CC > struct CallWrapper : public";
211 GenerateParamNumOverloadResolver( Out_, Overloads_, "\t\t\t", 0 );
213 Out_ << "\n\t\t{};\n";
217 int GenerateParamNumOverloadResolver( std::ostream& Out_,
218 const idlast::Overloads& Overloads_,
219 std::string Indent_,
220 int OvlId_ )
222 int minparams = Overloads_.begin()->first;
223 int maxparams = Overloads_.rbegin()->first;
225 if( minparams == maxparams )
227 OvlId_ = GenerateTypeOverloadResolver( Out_, Overloads_, Indent_, OvlId_ );
228 return OvlId_;
231 int split = ( minparams + maxparams ) / 2;
233 idlast::Overloads submap1( Overloads_.begin(), Overloads_.upper_bound( split ) );
234 idlast::Overloads submap2( Overloads_.upper_bound( split ), Overloads_.end() );
236 Out_ << '\n' << Indent_ << "OvlCountRes< CC, " << split << ",";
237 OvlId_ = GenerateParamNumOverloadResolver( Out_, submap1, Indent_ + '\t', OvlId_ );
238 Out_ << ",";
239 OvlId_ = GenerateParamNumOverloadResolver( Out_, submap2, Indent_ + '\t', OvlId_ );
240 Out_ << '\n' << Indent_ << ">";
242 return OvlId_;
245 int GenerateTypeOverloadResolver( std::ostream& Out_,
246 const idlast::Overloads& Overloads_,
247 std::string Indent_,
248 int OvlId_ )
250 if( Overloads_.size() == 1 )
252 Out_ << '\n' << Indent_ << "Overload" << OvlId_ << "< CC >";
253 return OvlId_ + 1;
256 Out_ << '\n' << Indent_ << "OvlTypeRes< CC,\n"
257 << Indent_ << '\t' << "Overload" << OvlId_ << "< CC >,";
258 idlast::Overloads::const_iterator it = Overloads_.begin();
259 ++it;
260 idlast::Overloads submap( it, Overloads_.end() );
261 OvlId_ = GenerateTypeOverloadResolver( Out_, submap, Indent_ + '\t', OvlId_ + 1 );
262 Out_ << '\n' << Indent_ << ">";
264 return OvlId_;