From 62c69c568763b47904f299fa2aecfa017bd71879 Mon Sep 17 00:00:00 2001 From: Henrik Tidefelt Date: Fri, 14 Nov 2008 16:09:24 +0100 Subject: [PATCH] Helper class for Structure creation in the kernel: Kernel::StructureFactory. This will soon be used by the Schur decomposition function, which will serve as example on how to use the factory. Basically, the idea is that a global instance of Kernel::StructureFactory is created for each structure signature. To create an instance of that structure, use the method to modify the fields held in the factory, and when all fields are set, use the method to create an instance. This is very non-functional, but pretty convenient. The danger is that one must not forget to set any fields before calling , or values from the last will be used without warning. Means to prevent this, such as clearing values after every , and checking for unset values upon , seems overly protective and costly. At least, the factory ensures that only declared fields are assigned, and it takes care of the not-so-obvious details of how to set up a new instance of Lang::Structure. --- source/containertypes.cc | 87 ++++++++++++++++++++++++++++++++++++++++++++++++ source/containertypes.h | 19 +++++++++++ 2 files changed, 106 insertions(+) diff --git a/source/containertypes.cc b/source/containertypes.cc index 6b09db97..ffdb3e4f 100644 --- a/source/containertypes.cc +++ b/source/containertypes.cc @@ -512,3 +512,90 @@ Lang::Structure::gcMark( Kernel::GCMarkedSet & marked ) const_cast< Lang::SingleList * >( values_.getPtr( ) )->gcMark( marked ); } + +Kernel::StructureFactory::StructureFactory( const std::list< const char * > & fields ) +{ + init( fields ); +} + +Kernel::StructureFactory::StructureFactory( const char * field1 ) +{ + std::list< const char * > fields; + fields.push_back( field1 ); + init( fields ); +} + +Kernel::StructureFactory::StructureFactory( const char * field1, const char * field2 ) +{ + std::list< const char * > fields; + fields.push_back( field1 ); + fields.push_back( field2 ); + init( fields ); +} + +Kernel::StructureFactory::StructureFactory( const char * field1, const char * field2, const char * field3 ) +{ + std::list< const char * > fields; + fields.push_back( field1 ); + fields.push_back( field2 ); + fields.push_back( field3 ); + init( fields ); +} + +Kernel::StructureFactory::StructureFactory( const char * field1, const char * field2, const char * field3, const char * field4 ) +{ + std::list< const char * > fields; + fields.push_back( field1 ); + fields.push_back( field2 ); + fields.push_back( field3 ); + fields.push_back( field4 ); + init( fields ); +} + +void +Kernel::StructureFactory::init( const std::list< const char * > & fields ) +{ + Ast::ArgListExprs * tmp = new Ast::ArgListExprs( false ); + typedef typeof fields ListType; + for( ListType::const_iterator i = fields.begin( ); i != fields.end( ); ++i ) + { + (*tmp->namedExprs_)[ *i ] = 0; + typedef typeof values_ MapType; + values_.insert( MapType::value_type( *i, Kernel::THE_VOID_VARIABLE ) ); + } + argList_ = tmp; +} + +void +Kernel::StructureFactory::clear( ) +{ + typedef typeof values_ MapType; + for( MapType::iterator i = values_.begin( ); i != values_.end( ); ++i ) + { + i->second = Kernel::THE_VOID_VARIABLE; + } +} + +void +Kernel::StructureFactory::set( const char * field, const Kernel::VariableHandle & value ) +{ + typedef typeof values_ MapType; + MapType::iterator i = values_.find( field ); + if( i == values_.end( ) ) + { + throw Exceptions::InternalError( "Kernel::StructureFactory::set: Field was not declared." ); + } + i->second = value; +} + +RefCountPtr< const Lang::Structure > +Kernel::StructureFactory::build( ) +{ + RefCountPtr< const Lang::SingleList > tmp = Lang::THE_CONS_NULL; + typedef typeof values_ MapType; + for( MapType::iterator i = values_.begin( ); i != values_.end( ); ++i ) + { + tmp = RefCountPtr< const Lang::SingleList >( new Lang::SingleListPair( i->second, tmp ) ); + } + return RefCountPtr< const Lang::Structure >( new Lang::Structure( argList_, tmp ) ); +} diff --git a/source/containertypes.h b/source/containertypes.h index 49d6fbc4..aa46cbfc 100644 --- a/source/containertypes.h +++ b/source/containertypes.h @@ -156,6 +156,25 @@ namespace Shapes }; } + namespace Kernel + { + class StructureFactory + { + const Ast::ArgListExprs * argList_; + std::map< const char *, Kernel::VariableHandle > values_; + private: + void init( const std::list< const char * > & fields ); + public: + StructureFactory( const std::list< const char * > & fields ); + StructureFactory( const char * field1 ); + StructureFactory( const char * field1, const char * field2 ); + StructureFactory( const char * field1, const char * field2, const char * field3 ); + StructureFactory( const char * field1, const char * field2, const char * field3, const char * field4 ); + void clear( ); + void set( const char * field, const Kernel::VariableHandle & value ); + RefCountPtr< const Lang::Structure > build( ); + }; + } } #endif -- 2.11.4.GIT