1 /*$Id: l_dispatcher.h,v 26.134 2009/11/29 03:47:06 al Exp $ -*- C++ -*-
2 * Copyright (C) 2006 Albert Davis
3 * Author: Albert Davis <aldavis@gnu.org>
5 * This file is part of "Gnucap", the Gnu Circuit Analysis Package
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3, or (at your option)
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 *------------------------------------------------------------------
22 * dispatcher -- for dynamically loaded modules
25 #ifndef L_DISPATCHER_H
26 #define L_DISPATCHER_H
27 #include "l_stlextra.h"
30 /*--------------------------------------------------------------------------*/
32 class INTERFACE DISPATCHER
{
34 std::map
<std::string
, T
*> * _map
;
38 _map
= new std::map
<std::string
, T
*>;
43 typedef typename
std::map
<std::string
, T
*>::const_iterator const_iterator
;
44 //class const_iterator : public std::map<std::string, T*>::const_iterator {};
46 const_iterator
begin()const {assert(_map
); return _map
->begin();}
47 const_iterator
end()const {assert(_map
); return _map
->end();}
49 void install(const std::string
& s
, T
* p
) {
50 assert(s
.find(',', 0) == std::string::npos
);
52 _map
= new std::map
<std::string
, T
*>;
56 // loop over all keys, separated by '|'
57 for (std::string::size_type
// bss: begin sub-string
58 bss
= 0, ess
= s
.find('|', bss
); // ess: end sub-string
59 bss
!= std::string::npos
;
60 bss
= (ess
!= std::string::npos
) ? ess
+1 : std::string::npos
,
61 ess
= s
.find('|', bss
)) {
62 std::string name
= s
.substr(bss
,
63 (ess
!= std::string::npos
) ? ess
-bss
: std::string::npos
);
64 trace2(name
.c_str(), bss
, ess
);
66 // quietly ignore empty string
67 }else if ((*_map
)[name
]) {
68 // duplicate .. stash the old one so we can get it back
69 error(bWARNING
, name
+ ": already installed, replacing\n");
70 std::string save_name
= name
+ ":0";
71 for (int ii
= 0; (*_map
)[save_name
]; ++ii
) {
72 save_name
= name
+ ":" + to_string(ii
);
74 (*_map
)[save_name
] = (*_map
)[name
];
75 error(bWARNING
, "stashing as " + save_name
+ "\n");
77 // it's new, just put it in
83 void uninstall(T
* p
) {
85 for (typename
std::map
<std::string
, T
*>::iterator
89 if (ii
->second
== p
) {
95 for (typename
std::map
<std::string
, T
*>::iterator
99 assert(ii
->second
!= p
);
104 void uninstall(const std::string
& s
) {
106 // loop over all keys, separated by '|'
107 for (std::string::size_type
// bss: begin sub-string
108 bss
= 0, ess
= s
.find('|', bss
); // ess: end sub-string
109 bss
!= std::string::npos
;
110 bss
= (ess
!= std::string::npos
) ? ess
+1 : std::string::npos
,
111 ess
= s
.find('|', bss
)) {
112 std::string name
= s
.substr(bss
,
113 (ess
!= std::string::npos
) ? ess
-bss
: std::string::npos
);
115 // quietly ignore empty string
116 }else if ((*_map
)[name
]) {
117 // delete, try to get back the old one
119 std::string save_name
= name
+ ":0";
120 for (ii
= 0; (*_map
)[save_name
]; ++ii
) {
121 save_name
= name
+ ":" + to_string(ii
);
124 save_name
= name
+ ":" + to_string(ii
-2);
125 (*_map
)[name
] = (*_map
)[save_name
];
126 (*_map
)[save_name
] = NULL
;
127 error(bWARNING
, "restoring " + save_name
+ " as " + name
+ "\n");
129 (*_map
)[name
] = NULL
;
132 error(bWARNING
, name
+ ": not installed, doing nothing\n");
137 T
* operator[](std::string s
) {
140 if (!rv
&& OPT::case_insensitive
) {
141 notstd::to_lower(&s
);
148 T
* operator[](CS
& cmd
) {
149 unsigned here
= cmd
.cursor();
152 //------------------------
154 //------------------------
162 T
* clone(std::string s
) {
163 T
* proto
= (*this)[s
];
165 return proto
->clone();
173 const std::string _name
;
177 INSTALL(DISPATCHER
<T
>* d
, const std::string
& name
, T
* p
) :
184 _d
->install(_name
, p
);
188 //_d->uninstall(_name);
193 /*--------------------------------------------------------------------------*/
194 /*--------------------------------------------------------------------------*/
196 // vim:ts=8:sw=2:noet: