13 // -------------------------------------------------------------------------
14 typedef std::set< std::string > TSet;
15 typedef std::map< std::string, TSet > TInstances;
16 typedef std::vector< std::string > TVector;
18 // -------------------------------------------------------------------------
19 TVector Tokenize( const std::string& str, const std::string& delims );
20 TSet Combine( const TSet& X, const TSet& Y );
22 std::string& str, const std::string& sub, const std::string& nsub
25 // -------------------------------------------------------------------------
26 int main( int argc, char* argv[] )
31 << "Usage: " << argv[ 0 ]
32 << " input_definitions dir library_name header_filename"
37 std::string input_definitions_file_name = argv[ 1 ];
38 std::string dir = argv[ 2 ];
39 std::string library_name = argv[ 3 ];
40 std::string head_fname = argv[ 4 ];
42 // Load file into a buffer
43 std::ifstream file_stream( input_definitions_file_name.c_str( ) );
47 << "Error opening file: \""
48 << input_definitions_file_name << "\""
54 file_stream.seekg( 0, std::ios::end );
55 buf.reserve( file_stream.tellg( ) );
56 file_stream.seekg( 0, std::ios::beg );
58 ( std::istreambuf_iterator< char >( file_stream ) ),
59 std::istreambuf_iterator< char >( )
62 std::istringstream input_str( buf );
66 TVector incl, first_incl;
69 while( std::getline( input_str, line ) )
71 if( line[ 0 ] == 'f' )
73 first_incl.push_back( line.substr( line.find_first_not_of( ' ', 1 ) ) );
75 else if( line[ 0 ] == 'i' )
77 incl.push_back( line.substr( line.find_first_not_of( ' ', 1 ) ) );
79 else if( line[ 0 ] == 'c' )
81 classes.push_back( line.substr( line.find_first_not_of( ' ', 1 ) ) );
83 else if( line[ 0 ] == 'a' )
85 TVector tokens = Tokenize( line, "=" );
88 TVector arg_tokens = Tokenize( tokens[ 0 ], " " );
89 std::string arg = arg_tokens[ 0 ];
91 while( arg[ 0 ] != '#' && i < arg_tokens.size( ) )
92 arg = arg_tokens[ ++i ];
95 TVector values_tokens = Tokenize( tokens[ 1 ], ";" );
96 for( auto t = values_tokens.begin( ); t != values_tokens.end( ); ++t )
98 std::string value = t->substr( t->find_first_not_of( ' ' ) );
99 unsigned int value_len = value.size( );
100 while( value[ value_len - 1 ] == ' ' && value_len > 0 )
102 value = value.substr( 0, value_len );
104 if( value == "#integers" )
106 instances[ arg ].insert( "char" );
107 instances[ arg ].insert( "short" );
108 instances[ arg ].insert( "int" );
109 instances[ arg ].insert( "long" );
110 instances[ arg ].insert( "unsigned char" );
111 instances[ arg ].insert( "unsigned short" );
112 instances[ arg ].insert( "unsigned int" );
113 instances[ arg ].insert( "unsigned long" );
115 else if( value == "#integers_ptr" )
117 instances[ arg ].insert( "char*" );
118 instances[ arg ].insert( "short*" );
119 instances[ arg ].insert( "int*" );
120 instances[ arg ].insert( "long*" );
121 instances[ arg ].insert( "unsigned char*" );
122 instances[ arg ].insert( "unsigned short*" );
123 instances[ arg ].insert( "unsigned int*" );
124 instances[ arg ].insert( "unsigned long*" );
126 else if( value == "#floats" )
128 instances[ arg ].insert( "double" );
129 instances[ arg ].insert( "float" );
131 else if( value == "#floats_ptr" )
133 instances[ arg ].insert( "double*" );
134 instances[ arg ].insert( "float*" );
136 else if( value == "#all_dims" )
138 instances[ arg ].insert( "1" );
139 instances[ arg ].insert( "2" );
140 instances[ arg ].insert( "3" );
141 instances[ arg ].insert( "4" );
143 else if( value == "#all_visual_dims" )
145 instances[ arg ].insert( "2" );
146 instances[ arg ].insert( "3" );
149 instances[ arg ].insert( value );
157 // Span all possible types
158 TVector all_real_classes;
159 for( auto clsIt = classes.begin( ); clsIt != classes.end( ); ++clsIt )
162 std::string name = clsIt->substr( clsIt->find_first_not_of( " " ) );
163 std::string tok = name;
164 auto sharpPos = tok.find_first_of( "#" );
166 while( sharpPos != std::string::npos )
168 tok = tok.substr( sharpPos );
169 auto spacePos = tok.find_first_of( " " );
170 auto arg = tok.substr( 0, spacePos );
171 auto aIt = instances.find( arg );
172 if( aIt != instances.end( ) )
173 li[ arg ] = aIt->second;
174 tok = tok.substr( spacePos );
175 sharpPos = tok.find_first_of( "#" );
184 auto iIt = li.begin( );
187 for( ; jIt != li.end( ); ++iIt, ++jIt )
189 if( iIt == li.begin( ) )
190 combs = Combine( iIt->second, jIt->second );
192 combs = Combine( combs, jIt->second );
197 combs = li.begin( )->second;
199 // Write instantiations
200 for( auto combIt = combs.begin( ); combIt != combs.end( ); ++combIt )
202 char* buffer = new char[ combIt->size( ) ];
203 std::strcpy( buffer, combIt->c_str( ) );
204 char* tok = std::strtok( buffer, "#" );
205 std::map< std::string, std::string > real_instance;
206 for( auto lIt = li.begin( ); lIt != li.end( ); ++lIt )
208 real_instance[ lIt->first ] = std::string( tok );
209 tok = std::strtok( NULL, "#" );
213 std::string real_name = name;
214 auto riIt = real_instance.begin( );
215 for( ; riIt != real_instance.end( ); ++riIt )
216 Replace( real_name, riIt->first, riIt->second );
217 all_real_classes.push_back( real_name );
223 all_real_classes.push_back( name );
228 std::ofstream out_str( head_fname.c_str( ) );
231 std::cerr << "Error opening file \"" << head_fname << "\"" << std::endl;
236 out_str << "#ifndef __" << dir << "__" << library_name << "__H__" << std::endl;
237 out_str << "#define __" << dir << "__" << library_name << "__H__" << std::endl << std::endl;
238 out_str << "#include <" << dir << "/" << library_name << "_Export.h>" << std::endl;
241 for( auto inclIt = first_incl.begin( ); inclIt != first_incl.end( ); ++inclIt )
243 << "#include <" << *inclIt << ">" << std::endl;
244 out_str << std::endl;
246 std::string base_name = dir + std::string( "_" ) + library_name;
249 << "#ifdef " << base_name << "_EXPORTS" << std::endl
250 << "# undef ITK_MANUAL_INSTANTIATION" << std::endl
251 << "# define " << base_name << "_PREFIX template class " << base_name << "_EXPORT" << std::endl
252 << "#else" << std::endl
253 << "# define ITK_MANUAL_INSTANTIATION" << std::endl
254 << "# define " << base_name << "_PREFIX extern template class" << std::endl
255 << "#endif" << std::endl << std::endl;
258 for( auto inclIt = incl.begin( ); inclIt != incl.end( ); ++inclIt )
260 << "#include <" << *inclIt << ">" << std::endl;
261 out_str << std::endl;
264 for( auto clsIt = all_real_classes.begin( ); clsIt != all_real_classes.end( ); ++clsIt )
266 << base_name << "_PREFIX " << *clsIt << ";" << std::endl;
267 out_str << std::endl;
269 out_str << "#endif // __" << dir << "__" << library_name << "__H__" << std::endl;
270 out_str << std::endl << "// eof" << std::endl;
277 // -------------------------------------------------------------------------
278 TVector Tokenize( const std::string& str, const std::string& delims )
281 if( str.size( ) > 0 )
283 char* buffer = new char[ str.size( ) + 1 ];
284 std::strcpy( buffer, str.c_str( ) );
285 buffer[ str.size( ) ] = '\0';
286 char* it = std::strtok( buffer, delims.c_str( ) );
289 tokens.push_back( std::string( it ) );
290 it = std::strtok( NULL, delims.c_str( ) );
299 // -------------------------------------------------------------------------
300 TSet Combine( const TSet& X, const TSet& Y )
303 for( auto xIt = X.begin( ); xIt != X.end( ); ++xIt )
305 for( auto yIt = Y.begin( ); yIt != Y.end( ); ++yIt )
307 std::stringstream val;
308 val << *xIt << "#" << *yIt;
309 Z.insert( val.str( ) );
317 // -------------------------------------------------------------------------
319 std::string& str, const std::string& sub, const std::string& nsub
325 index = str.find( sub, index );
326 if( index == std::string::npos ) break;
327 str.replace( index, sub.size( ), nsub );
328 index += sub.size( );