From 44ff9b6279705bc8948bfd3cf43230c915c9b9b0 Mon Sep 17 00:00:00 2001 From: "Joachim Wuttke (h)" <j.wuttke@fz-juelich.de> Date: Tue, 27 Oct 2015 18:11:48 +0100 Subject: [PATCH] NGeni -> SGeniRegistry, to ensure clean tear-down. --- TODO | 2 ++ pub/lib/commands.cpp | 2 +- pub/lib/fregistry.hpp | 2 +- pub/lib/func.hpp | 1 + pub/lib/geni.cpp | 19 ++++++------------- pub/lib/geni.hpp | 14 ++++++++------ pub/lib/registry.hpp | 38 +++++++++++++++++++++++++++++++++++--- pub/lib/toplevel.cpp | 5 ++++- pub/lib/xax_lex.lpp | 3 ++- 9 files changed, 60 insertions(+), 26 deletions(-) diff --git a/TODO b/TODO index 9fb20cc7..ef621e21 100644 --- a/TODO +++ b/TODO @@ -1,5 +1,7 @@ == Todo at once == +refactor func+op registration so that registered object can be const + or+: value does not arrive! cp: table header placement, correct 1-R^2 diff --git a/pub/lib/commands.cpp b/pub/lib/commands.cpp index 0e564eaa..8e05a12d 100644 --- a/pub/lib/commands.cpp +++ b/pub/lib/commands.cpp @@ -103,7 +103,7 @@ bool frida_command( string cmd ) " hic dimension-reducing functionals of curves\n" ; } else if (cmd == "hid" || cmd == "oio") { - NGeni::display_genis(); + SGeniRegistry::get_instance()->display_genis(); } else if (cmd == "hic") { NCvin::display_cvins(); } else if (cmd == "ho") { diff --git a/pub/lib/fregistry.hpp b/pub/lib/fregistry.hpp index f352f976..21be3258 100644 --- a/pub/lib/fregistry.hpp +++ b/pub/lib/fregistry.hpp @@ -47,7 +47,7 @@ typedef void (*func_e_eee) (double&,double&, double,double, double,double, dou //! A singleton class, holding a collection of CFunc's. -class SFuncRegistry : public IRegistry<CFunc>, public ISingleton<SFuncRegistry> { +class SFuncRegistry : public IRegistryTmp<CFunc>, public ISingleton<SFuncRegistry> { private: virtual string type_name() const { return "operator and function"; } void register_fct_template( diff --git a/pub/lib/func.hpp b/pub/lib/func.hpp index c10252d3..e56d2953 100644 --- a/pub/lib/func.hpp +++ b/pub/lib/func.hpp @@ -43,6 +43,7 @@ class CFuncMetadata { class CFunc : public CFuncMetadata { public: CFunc( const CFuncMetadata& _m ) : CFuncMetadata( _m ) {} + ~CFunc() { for( auto t: tyfuList ) delete t; } vector<const CTypedFunc*> tyfuList; //! List of available typed function instances. const CTypedFunc* find_exact_tyfu( string intypes ) const; const CTypedFunc* find_tyfu( string intypes, bool want_error ) const; diff --git a/pub/lib/geni.cpp b/pub/lib/geni.cpp index 1146584f..fb982b50 100644 --- a/pub/lib/geni.cpp +++ b/pub/lib/geni.cpp @@ -268,19 +268,12 @@ CGeni::CGeni( string _name, int _narg, string _default_arg_str, geni_eval _eval, default_arg[iarg] = user_xaxparse( default_expr[iarg].c_str() ); } -const CGeni* NGeni::find( string key ) -{ - auto pos = gmap.find(key); - return pos == gmap.end() ? nullptr : pos->second; -} - void CGeni::register_me() const { - NGeni::gmap.insert( make_pair( name, this ) ); - NGeni::glist.push_back( this ); + SGeniRegistry::get_instance()->push_back( name, this ); } -void NGeni::display_genis() +void SGeniRegistry::display_genis() const { cout << "Dimension-reducing functionals of data sets.\n"; cout << "Usage:\n"; @@ -293,13 +286,13 @@ void NGeni::display_genis() cout << " - list shows default arguments that are assumed when functional name is not\n"; cout << " followed by a parenthesis: 'integral' is shorthand for 'integral(x,y)'\n"; cout << "Implemented functionals:\n"; - for( auto g = glist.begin(); g!=glist.end(); ++g ) { - string s1 = (*g)->name + "(" + (*g)->default_arg_str + ")"; - cout << " " << str( format("%-14s") % s1 ) << (*g)->com << "\n"; + for( const CGeni* g: FList ) { + string s1 = g->name + "(" + g->default_arg_str + ")"; + cout << " " << str( format("%-14s") % s1 ) << g->com << "\n"; } } -void NGeni::initialize() +void SGeniRegistry::initialize() { // operators by precedence (as in xax_yacc.ypp): (new CGeni( "valmin", 1, "y", geni_valmin, "a", diff --git a/pub/lib/geni.hpp b/pub/lib/geni.hpp index dc803146..050f510e 100644 --- a/pub/lib/geni.hpp +++ b/pub/lib/geni.hpp @@ -7,6 +7,7 @@ //! \file geni.hpp //! \brief Collection NGeni of generalized integral wrappers CGeni. +#include "registry.hpp" //! Function type: Evaluate generalized integral for given vector(s). @@ -32,10 +33,11 @@ class CGeni { }; -//! Collection of function wrappers CFunc +class SGeniRegistry : public IRegistry<CGeni>, public ISingleton<SGeniRegistry> { + private: + virtual string type_name() const { return "generalized integrals"; } + public: + void display_genis() const; + static void initialize(); +}; -namespace NGeni { // public (short) interface - void initialize(); - const CGeni* find( string nam ); - void display_genis(); -} diff --git a/pub/lib/registry.hpp b/pub/lib/registry.hpp index bf63ead3..6e53d969 100644 --- a/pub/lib/registry.hpp +++ b/pub/lib/registry.hpp @@ -13,20 +13,52 @@ #include "defs.hpp" #include "singleton.hpp" +//! Mixin interface for registries holding objects of type T; temporary version for SFuncRegistry. + +template<class T> +class IRegistryTmp { + protected: + virtual string type_name() const = 0; + map<string, /*const*/T*> FMap; //! unsorted hash, for expression evaluation + vector<const T*> FList; //! sorted array, for help text + public: + virtual ~IRegistryTmp() { for ( const T* F: FList ) delete F; } + void push_back( const string& key, const T* val ){ + if ( FMap.find(key) != FMap.end() ) + throw "Duplicate registry entry " + key; + FMap.insert( std::make_pair( key, val ) ); + FList.push_back( val ); + } + const T* find( const string& key ) const { + auto pos = FMap.find(key); + return pos == FMap.end() ? nullptr : pos->second; } + const T* find_or_fail( const string& key ) const { + const T* ret = find( key ); + if( !ret ) + throw "Cannot find '" + key + "' in " + type_name() + " registry"; + return ret; } +}; + //! Mixin interface for registries holding objects of type T template<class T> class IRegistry { protected: virtual string type_name() const = 0; - map<string,T*> FMap; //! unsorted hash, for expression evaluation + map<string, const T*> FMap; //! unsorted hash, for expression evaluation vector<const T*> FList; //! sorted array, for help text public: virtual ~IRegistry() { for ( const T* F: FList ) delete F; } - const T* find( string key ) const { + void push_back( const string& key, const T* val ){ + if ( FMap.find(key) != FMap.end() ) + throw "Duplicate registry entry " + key; + FMap.insert( std::make_pair( key, val ) ); + FList.push_back( val ); + } + const T* find( const string& key ) const { auto pos = FMap.find(key); return pos == FMap.end() ? nullptr : pos->second; } - const T* find_or_fail( string key ) const { + const T* find_or_fail( const string& key ) const { const T* ret = find( key ); if( !ret ) throw "Cannot find '" + key + "' in " + type_name() + " registry"; diff --git a/pub/lib/toplevel.cpp b/pub/lib/toplevel.cpp index f8b4a94a..6b575542 100644 --- a/pub/lib/toplevel.cpp +++ b/pub/lib/toplevel.cpp @@ -41,6 +41,8 @@ void fstring_initialize(); // implemented in fstring.cpp; no .hpp file // Initializiations. auto GFuncRegistry = SFuncRegistry::get_instance(); // global for use in xax_lex and xax_yacc +auto GGeniRegistry = SGeniRegistry::get_instance(); // global for use in xax_lex and xax_yacc + SRegistry* GReg = &(SRegistry::getInstance()); @@ -63,6 +65,7 @@ void my_gsl_error_handler ( const char * reason, const char * file, int line, in void atexit_handler() { SFuncRegistry::reset_instance(); + SGeniRegistry::reset_instance(); } @@ -141,7 +144,7 @@ CFrida::CFrida() fbase_initialize(); fassign_initialize(); fstring_initialize(); - NGeni::initialize(); + SGeniRegistry::initialize(); NCvin::initialize(); if( std::atexit( atexit_handler ) ) { diff --git a/pub/lib/xax_lex.lpp b/pub/lib/xax_lex.lpp index 37044b0c..e17e007e 100644 --- a/pub/lib/xax_lex.lpp +++ b/pub/lib/xax_lex.lpp @@ -59,6 +59,7 @@ RNode node_PI( new CNodeVal( M_PI ) ); RNode node_INF( new CNodeVal( INFINITY ) ); extern SFuncRegistry* GFuncRegistry; +extern SGeniRegistry* GGeniRegistry; %} DIG [0-9] @@ -156,7 +157,7 @@ e { xaxlval->t = node_E; xaxlval->p = (void*) f1; return FNCT; } - if ( const CGeni* g1 = NGeni::find(xaxtext) ) { + if ( const CGeni* g1 = GGeniRegistry->find(xaxtext) ) { xaxlval->p = (void*) g1; return GENI; } -- GitLab