   libindustry [ overengineered factory template class! ]
  libindustryMy generic components library, released under the Boost license.  The main focal point of the library is currently the most overengineered factory classes for C++, ever, that I am aware of, with plans for much more!News5/31/06 - libindustry-0.2 has now been released!This version comes after a few days of refactoring, and now supports boost::any, boost::variant*, boost::shared_ptr, std::auto_ptr, and raw pointers.  create(id,...) now correctly throws an exception if a type hasn't been registered with type<T>(), and the new syntax for factory instantiation (no need for the methods<> wrapper there, although it is still supported).Compile times are growing, compile optimization will end up on the TODO list soon.  Still reasonable if you ask me.* Note: You must still register the individual types with type<T> when using boost::variant.  This should be done automatically in a future release, hopefully.5/27/06 - libindustry-0.1.1 has now been released!Got access to my windows computer again, now compiles on VS2k5, added the missing return keyword in industry::type's comparison operators.  Added -Wall to my internal build system's flags so an error like that won't make it to release again (so shameful!)5/21/06 - libindustry-0.1 is has now been released!The DownloadLatest version: http://homepage.mac.com/pandamojo/industry/industry-0.2.zipThe library is header-only, just copy and go!  Source files included within the zip are tests/examples.RequirementsThe Boost Library (Preprocessor and Any, currently)CompatibilityVisual Studio 2005 Express (tested OK 0.2)GCC 4.0.0 (tested OK 0.2)Example: test.factory.cpp (0.2)// Copyright (c) 2006 Michael B. Edwin Rickert//// Distributed under the Boost Software License, Version 1.0.// (See accompanying file LICENSE_1_0.txt or copy at// http://www.boost.org/LICENSE_1_0.txt )//// May 31, 2006 - Some refactoring, templatized test function and tested for all 5 currently supported types// May 31, 2006 - Re-enabled invalid type test (throws instead of asserts now)// May 27, 2006 - Disabled intentional assert, added void(void) to the test// May 21, 2006 - Created#include "industry.factory.hpp"#include <boost/array.hpp>#include <iostream>#include <cassert>struct base { virtual ~base() {} };struct foo : base {foo( void ){ std::cout << "foo( void )" << std::endl; }foo( int n )    { std::cout << "foo( int " << n << " )" << std::endl; }foo( char c )   { std::cout << "foo( char " << c << " )" << std::endl; }foo( int a , int b ) { std::cout << "foo( int a " << a << " , int b " << b << " )" << std::endl; }foo( const foo & )   { std::cout << "foo( const foo & )" << std::endl; }};struct bar : base {bar( void ){ std::cout << "bar( void )" << std::endl; }bar( int n )    { std::cout << "bar( int " << n << " )" << std::endl; }bar( char c )   { std::cout << "bar( char " << c << " )" << std::endl; }bar( int a , int b ) { std::cout << "bar( int a " << a << " , int b " << b << " )" << std::endl; }bar( const foo & )   { std::cout << "bar( const bar & )" << std::endl; }};template < typename T > void verify( const boost::any & any ) {std::cout << "Verifying boost::any == T ..." << std::flush;boost::any_cast< T >( any ); //should throw on failurestd::cout << "OK!" << std::endl;}template < typename T , typename B > void verify( const boost::shared_ptr<B> & ptr ) {std::cout << "Verifying boost::shared_ptr<B> == T ..." << std::flush;assert( dynamic_cast< T* >( ptr.get() ) );std::cout << "OK!" << std::endl;}template < typename T , typename B > void verify( const std::auto_ptr<B> & ptr ) {std::cout << "Verifying std::auto_ptr<B> == T ..." << std::flush;assert( dynamic_cast< T* >( ptr.get() ) );std::cout << "OK!" << std::endl;}template < typename T , BOOST_PP_ENUM_PARAMS( BOOST_VARIANT_LIMIT_TYPES , typename V ) >void verify( const boost::variant< BOOST_PP_ENUM_PARAMS( BOOST_VARIANT_LIMIT_TYPES , V ) > & variant ) {std::cout << "Verifying boost::variant< ... > == T ..." << std::flush;boost::get< T >( variant ); //should throw on failurestd::cout << "OK!" << std::endl;}template < typename T , typename B > void verify( B * ptr ) {std::cout << "Verifying B * == T ..." << std::flush;assert( dynamic_cast< T* >( ptr ) );std::cout << "OK!" << std::endl;}template < typename InterfaceT >void test_factory_interface( void ) {industry::factory< InterfaceT , industry::methods< void ( void ) , void ( int ) , void( char ) , void ( int , int ) > > factory_via_methods;industry::factory< InterfaceT , void ( void ) , void ( int ) , void( char ) , void ( int , int ) > factory;factory.template type< foo >();factory.template type< bar >();boost::array< industry::type , 2 > types = { typeid(foo) , typeid(bar) };boost::array< InterfaceT , 2 > example;for ( unsigned i = 0 ; i < 2 ; ++i ) {example = factory.create( types , 42 );}verify< foo >( example[0] );verify< bar >( example[1] );InterfaceT v  = factory.create( typeid(foo) );InterfaceT u  = factory.create( typeid(foo) , 42 );InterfaceT c  = factory.create( typeid(foo) , 'c' );InterfaceT uu = factory.create( typeid(foo) , 42 , 42 );bool threw = false;try { //will throw bad_factory_type, hasn't been added with type<>()InterfaceT baz = factory.create( typeid(int) , 42 );} catch( industry::bad_factory_type ) {threw = true;}assert( threw );std::cout << "====================================" << std::endl;}void test_shared_ptr_factory( void ) {industry::factory< boost::shared_ptr< base > , void ( void ) , void ( int ) , void ( char ) , void ( int , int ) > factory;factory.type< foo >();factory.type< bar >();boost::array< industry::type , 2 > types = { typeid(foo) , typeid(bar) };boost::array< boost::shared_ptr< base > , 2 > example;for ( unsigned i = 0 ; i < 2 ; ++i ) {example = factory.create( types , 42 );}}void test_factory( void ) {test_factory_interface< boost::any >();test_factory_interface< std::auto_ptr< base > >();test_factory_interface< boost::shared_ptr< base > >();test_factory_interface< boost::variant< foo , bar > >();test_factory_interface< base * >(); //WARNING: Will leak, I'm a lazy bum.}Results (as expected):Beginning test...foo( int 42 )foo( const foo & )foo( const foo & )foo( const foo & )bar( int 42 )Verifying boost::any == T ...foo( const foo & )OK!Verifying boost::any == T ...OK!foo( void )foo( const foo & )foo( const foo & )foo( int 42 )foo( const foo & )foo( const foo & )foo( char c )foo( const foo & )foo( const foo & )foo( int a 42 , int b 42 )foo( const foo & )foo( const foo & )====================================foo( int 42 )bar( int 42 )Verifying std::auto_ptr == T ...OK!Verifying std::auto_ptr == T ...OK!foo( void )foo( int 42 )foo( char c )foo( int a 42 , int b 42 )====================================foo( int 42 )bar( int 42 )Verifying boost::shared_ptr == T ...OK!Verifying boost::shared_ptr == T ...OK!foo( void )foo( int 42 )foo( char c )foo( int a 42 , int b 42 )====================================foo( void )foo( void )foo( int 42 )foo( const foo & )foo( const foo & )bar( int 42 )Verifying boost::variant< ... > == T ...OK!Verifying boost::variant< ... > == T ...OK!foo( void )foo( const foo & )foo( const foo & )foo( int 42 )foo( const foo & )foo( const foo & )foo( char c )foo( const foo & )foo( const foo & )foo( int a 42 , int b 42 )foo( const foo & )foo( const foo & )====================================foo( int 42 )bar( int 42 )Verifying B * == T ...OK!Verifying B * == T ...OK!foo( void )foo( int 42 )foo( char c )foo( int a 42 , int b 42 )====================================All succeeded!Press any key to continue . . .[Edited by - MaulingMonkey on May 31, 2006 8:32:04 PM]
  A great way of adding more over-engineering to that interface would be to make industry::methods<> actually be a typelist (so you could have any number of those). I'm just sayin'... :-);Quote:Original post by hplus0603A great way of adding more over-engineering to that interface would be to make industry::methods<> actually be a typelist (so you could have any number of those). I'm just sayin'... :-)I was originally using boost::mpl containers, but the messyness of having to use "typename container<...>::type" in many places, besides only working with one mpl container, made me decide to use a simpler typedef.In the next phases of refactoring, the current factory class will probably become factory_base.  The new factory template will be N-ary template argumented, so the methods<> list will be un-necessary.  I'll add partial specializations to allow the current factory< T , methods< ... > > syntax, and probably factory< T , boost::mpl::container< ... >::type > as well.  I'll extend methods< ... > if it makes refactoring easier, but with these changes, boost::mpl should be a better alternative (pre-existing usage, more advanced, etc)Internal refactoring is also on the list, namely, pulling the boost::any related specifics out and into their own "plugin" template, which should ease the creation of boost::factory< boost::shared_ptr<T> | boost::scoped_ptr<T> | std::auto_ptr<T> | T * | users_custom_smart_ptr_class< T > >.I'm also considering relaxing the restrictions on the return type of methods, currently they're required to be void (whereas boost::any might be more "appropriate", and in the end, any return type would be okay since it's replaced anyways).  *shrug*   ;  libindustry-0.2 has been released!!!   