|Subject:||Re: Fwd: Considering adding a "dispatch" function for compile-time polymorphism|
|Date:||Fri, 8 Aug 2014 10:21:43 -0600|
I can see the value of having a unified approach to dispatching on
type, but I'm a bit reluctant to accept your current solution because
it seems to add considerable complexity that I find somewhat hard to
follow. For example, I find a number of the function and object names
confusing, so maybe improving those would make the code easier for me
Here are some specific comments. I'm looking at revision c689ac34114d
in your archive at http://hg.octave.org/octave-dspies.
Since this object is inside the namespace find, is it necessary for it
to be called "find_result"? Maybe just "result"?
// This is the generic "find" method for all matrix types. All calls to
// "find" get routed here one way or another as this method contains logic
// for determining the proper output dimensions and handling forward/reversed,
// n_to_find etc.
// It would be unwise to try and duplicate this logic elsewhere as it's fairly
// nuanced and unintuitive (but Matlab compatible).
template<direction dir, typename MT, typename R>
find_to_R (dir_handler<dir> dirc, const MT& v, octave_idx_type n_to_find,
If this function creates/fills resvec, why not just return resvec
instead of passing it by reference?
What does "find_to_R" mean? This name is confusing to me. If this is
the 'generic "find" method', then why not just call it "find"? Is
this function supposed to be called by users, or is it really an
// The method call used for internal liboctave calls to find. It constructs
// an find_result and fills that rather than a res_type_of (see "find.cc").
// Note that this method only supports full arrays because octave_idx_type
// will generally overflow if used to represent the nonzero indices of sparse
// arrays. Instead consider using the sparse-iterator class from
// nz-iterators.h to avoid this problem
find (const Array<ELT_T>& v, octave_idx_type n_to_find = -1, direction dir =
find_to_R (dirc_forward, v, n_to_find, resvec);
find_to_R (dirc_back, v, n_to_find, resvec);
liboctave_fatal ("find: unknown direction: %d; must be 1 or -1", dir);
Would it be better to have find and rfind functions to handle the
forward and backward find operations?
If not, and the direction parameter is needed, then is it necessary to
bother with the default case here? Since direction is an enum, can it
ever have values other than forward or backward?
It might also be better to report forward and backward instead of 1and -1 in the error message.
template<int nargout, typename T>
Is this called ffind because DEFUN generates a function called Ffind?
I guess I would just call it "find_result", though again, since this
is inside the "find" namespace, maybe it should just be called "result".
// Calls the to_R template method in "find.h" which
// in turn will fill in resvec of type ffind_result (see above).
// This is generic enough to work for any matrix type M
template<direction dir, int nargout, typename M>
call (const M& v, octave_idx_type n_to_find)
I guess n_to_find is the number of elements to find? That's somewhat
confusing given the other "find_to_R" function name.
ffind_result<nargout, typename M::element_type> resvec;
find_to_R (dirc, v, n_to_find, resvec);
return resvec.get_list ();
It seems to me this could just be:
result<nargout, typename M::element_type> resvec
= find_to_R (dir_handler<dir>, v, num_elts_to_find);
return resvec.get_list ();
Or maybe just
find_to_R (dir_handler<dir>, v, num_elts_to_find) . get_list ();
but then I'm left wondering why the "call" template function is needed.
// A large annoying plethora of switch statements necessary to
I find comments like this to be annoying. :-/
template<int nargout, typename M>
dir_to_template (const M& v, octave_idx_type n_to_find, direction dir)
return call<BACKWARD, nargout> (v, n_to_find);
return call<FORWARD, nargout> (v, n_to_find);
return octave_value_list ();
Names like dir_to_template don't tell me much. The purpose of this
function is what? To handle the fact that DIR can't be a template
parameter, so you switch over the possible values of DIR?
should just have find and rfind functions instead? Or simply pass the
direction of the find operation as an argument instead of generating
separate templates based on direction? Why is it necessary to have
the direction be a template parameter?
nargout_to_template (const M& v, int nargout, octave_idx_type n_to_find,
return dir_to_template<1> (v, n_to_find, dir);
return dir_to_template<2> (v, n_to_find, dir);
return dir_to_template<3> (v, n_to_find, dir);
panic_impossible (); // Checked by *** in Ffind
return octave_value_list ();
This function seems to be used in only one place. Is it necesary to
have it as a separate function? Why not just put the switch inside
your "find_templated" function?
// This functor will be called by dispatch.h with the proper type M.
// This avoids having to explicitly list the different types find can
// handle and instead delegates that duty to the generic "dispatch"
operator() (const M& v, const find_info& inf)
return nargout_to_template (v, inf.nargout, inf.n_to_find, inf.dir);
Why call this "find_templated"? I don't think that naming functions
"templated" helps much with understanding what the functions are
If you've packaged the find_info in a struct, why split it out here?
Why not continue to pass it down to other functions as a struct until
the individual elements are actually needed?
|[Prev in Thread]||Current Thread||[Next in Thread]|