Dear Ralf, On Thu, 17 Jun 2004, Ralf Stephan wrote:
thanks for the detailed reply. Const correctness is noted for my next submission (which will be to you), as well as testing. I understand from your comments that, while factor() will go into CLN, divisors() won't.
No, I didn't say that. What's the implementation of divisors anyways? You factorize, and then build all possible permutations of the factors, taking into account their multiplicities, right? Is there anything else one can do that I'm not aware of? Anyways, I see no reason why it shouldn't go into CLN, even if it is only a minor wrapper function for factor(). Is there any?
Now I do have two questions: What do you mean by adapting CLN's memory scheme to STL?
As far as I understand, CLN doesn't use new/delete and its objects are allocated using malloc_hook. OTOH, it may not be sufficient to malloc_hook sizeof(std::vector<...>) and give that to the caller since STL might itself allocate space using its own (default) allocator in the process. If that is really of concern, the solution could be to write an allocator (STL object) using malloc_hook for that and other cases. That was what I meant.
Meanwhile, I favor moving the burden of space allocation to the caller via working on a referenced vector of pairs of cl_Is.
Sorry, I still don't understand why you'ld have to fiddle with malloc_hook if all you're dealing with are the cl_I objects that have value semantics.
The user-visible side of the bridge constitute perfectly copyable objects with value semantics and are hence suited for STL, right?
CLN's objects are suited for STL, of course, since STL uses the object's interface. I was sceptical about the reverse, i.e., if STL deletes everything(!) it creates with its normal malloc. The user relies on garbage collection of an STL container with CLN objects that is returned by CLN.
I'm still confused. Are you worried about heap storage allocated by CLN and not freed early enough by the STL container's dtors? Even if the STL container dtors don't return everything to the system, they have to invoke their elements' dtors right away, thus ensuring that CLN doesn't leak, right? Please correct me if I misunderstand.
But the point is moot, anyway, with factor having the interface
int factor (const cl_I& n, std::vector<std::pair<cl_I,cl_I> >& pv);
We don't need a cl_I for the multiplicities - machine precision integers are more than enough. Also, I would recommend to declare a type representing factors and their multiplicity instead of using pair<cl_I,uintC>. Also, what's the integer return value, anyway? Wouldn't the prototype std::vector<somethingContaining_cl_I_and_unsigned> factor(const cl_I&); give us more natural syntax? I can't see much sense in C-like argument shuttling.
Just have a look at the Bernoulli number cache in GiNaC. Second, is std::list< factor_exponent_pair_or_whatever > really a wise decision?
I used the word 'list' not careful enough, sorry. I meant 'container'.
Ah, okay. Best wishes -richy. -- Richard B. Kreckel <http://www.ginac.de/~kreckel/>