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/>.
21 #include "core/idlast/namespace.h"
26 using namespace fail::failit
;
32 void GenerateFunctionTraits( std::ostream
& Out_
,
33 const idlast::Overloads
& Overloads_
,
38 int GenerateParamNumOverloadResolver( std::ostream
& Out_
,
39 const idlast::Overloads
& Overloads_
,
43 int GenerateTypeOverloadResolver( std::ostream
& Out_
,
44 const idlast::Overloads
& Overloads_
,
49 void fail::failit::GenerateMethodTraits( std::ostream
& Out_
,
50 const idlast::Class
* pClass_
,
51 const idlast::Method
* pMtd_
,
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();
63 std::stringstream tagstring
;
64 tagstring
<< "class_traits< " << FullClassName
<< " >::";
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"
75 "\t\tstatic const char* Name() { return \"" << pMtd_
->getName() << "\"; }\n";
77 GenerateFunctionTraits( Out_
, pMtd_
->getOverloads(), bStatic_
, pMtd_
->getName().c_str(), false );
82 void fail::failit::GenerateCtorTraits( std::ostream
& Out_
,
83 const idlast::Class
* pClass_
,
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();
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"
102 "\t\tstatic const char* Name() { return \"ctor_\"; }\n";;
104 GenerateFunctionTraits( Out_
, pClass_
->getConstructors(), false, NULL
, bStruct_
);
112 void GenerateFunctionTraits( std::ostream
& Out_
,
113 const idlast::Overloads
& Overloads_
,
118 idlast::Overloads::const_iterator ovit
;
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";
129 Out_
<< "Overload" << ovlcount
;
133 "\t\t\tstatic bool Call( CC& CallContext_ )\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() )
161 // No name: this is a constructor.
162 Out_
<< "CallContext_.template constructObject(";
165 // Plain method call, with or without a return value...
166 if( Params
.getReturnType() )
168 Out_
<< "CallContext_.template setReturnValue\n"
170 PrintTypeCategory( Out_
, Params
.getReturnType() );
172 PrintType( Out_
, Params
.getReturnType() );
177 // And either static or not.
183 Out_
<< pName_
<< '(';
186 for( paramit
= Params
.begin(); paramit
!= Params
.end(); ++paramit
)
188 if( paramit
!= Params
.begin() )
190 Out_
<< ' ' << paramit
->first
;
193 if( !Params
.empty() )
198 if( pName_
&& Params
.getReturnType() )
202 "\t\t\t\treturn true;\n"
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_
,
222 int minparams
= Overloads_
.begin()->first
;
223 int maxparams
= Overloads_
.rbegin()->first
;
225 if( minparams
== maxparams
)
227 OvlId_
= GenerateTypeOverloadResolver( Out_
, Overloads_
, Indent_
, 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_
);
239 OvlId_
= GenerateParamNumOverloadResolver( Out_
, submap2
, Indent_
+ '\t', OvlId_
);
240 Out_
<< '\n' << Indent_
<< ">";
245 int GenerateTypeOverloadResolver( std::ostream
& Out_
,
246 const idlast::Overloads
& Overloads_
,
250 if( Overloads_
.size() == 1 )
252 Out_
<< '\n' << Indent_
<< "Overload" << OvlId_
<< "< CC >";
256 Out_
<< '\n' << Indent_
<< "OvlTypeRes< CC,\n"
257 << Indent_
<< '\t' << "Overload" << OvlId_
<< "< CC >,";
258 idlast::Overloads::const_iterator it
= Overloads_
.begin();
260 idlast::Overloads
submap( it
, Overloads_
.end() );
261 OvlId_
= GenerateTypeOverloadResolver( Out_
, submap
, Indent_
+ '\t', OvlId_
+ 1 );
262 Out_
<< '\n' << Indent_
<< ">";