Re: Removal of string-based object resolution
Posted by Luigi Ballabio-2 on
URL: http://quantlib.414.s1.nabble.com/Removal-of-string-based-object-resolution-tp3371p3372.html
On 2004.10.11 14:45, Andre Louw wrote:
> I notice that all the string-based object resolution have been removed
> from the SWIG wrapper files (calendars, currencies, daycounters). Is
> there an alternative mechanism that I'm missing to resolve specific
> implementations of these classes based on an input string?
Andre,
you can add the following in the .i file:
%extend Calendar {
Calendar(const std::string& name) {
if (name == "USA") return new Calendar(UnitedStates());
else if ....
}
}
to get back the old behavior. If you're worried about performance, you can
tailor the above to your usage by checking first the calendars you use most
frequently.
> Without this mechanism I would have to resolve this in Python, which I'm
> assuming "off the cuff" would have a performance impact?
In principle, but I don't think it would matter much if you, say, create a
Calendar, pass it to a Schedule, build a bond and price it---the creation
overhead should be negligible compared to the work done later. Also, see
below.
> If there is no alternative, any objections to reworking this to include
> all the latest implementations?
Well, on the one hand I was trying to remove redundancy and have one less
thing to maintain. On the other hand, one might want to customize the
strings used---because, say, his database uses different names, or he wants
'USA' to mean the Bond market calendar rather than the Stock exchange, and
that is more difficult if I write _my_ strings in stone--or in the
wrappers, which is practically the same thing. I'd suggest storing a few
calendar instances in a Python dictionary when one loads the module, as in:
my_calendars = {
'USA': UnitedStates(),
'TARGET': TARGET(),
...
}
and use my_calendars[name] instead of Calendar(name). Or you can even
write:
def _init_calendar(self,name):
self.this = my_calendars[name]
self.thisown = 0
Calendar.__init__ = _init_calendar
and keep using Calendar(name). This might actually improve performance, as
you would get a reference to an already created calendar instead of
allocating new memory in order to create one (*).
Later,
Luigi
(*) technical note: the wrapper code could not be written simply as
if (name == "USA") return new UnitedStates;
as the pointer would have been cast to Calendar* and later deleted as such.
Since the Calendar class has no virtual destructor, the above would be
undefined behavior according to the C++ standard. Instead, the code had to
be written as:
if (name == "USA") return new Calendar(UnitedStates());
i.e., an initialization, an allocation with new, and a copy---inefficient,
and just plain twisted.