octave-maintainers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Branching on builtin_type ()


From: Jordi Gutiérrez Hermoso
Subject: Re: Branching on builtin_type ()
Date: Mon, 5 Mar 2012 18:16:24 -0500

2012/3/5 John W. Eaton <address@hidden>:
> On  5-Mar-2012, Jordi Gutiérrez Hermoso wrote:
>
> | While reading Jaroslav's code, I frequently come across constructs
> | like this one:
> |
> |           switch (argx.builtin_type ())
> |             {
> |             case btyp_double:
> |               retval = argx.array_value ().nth_element (n, dim);
> |               break;
> |             case btyp_float:
> |               retval = argx.float_array_value ().nth_element (n, dim);
> |               break;
> |             case btyp_complex:
> |               retval = argx.complex_array_value ().nth_element (n, dim);
> |               break;
> |             case btyp_float_complex:
> |               retval = argx.float_complex_array_value ().nth_element (n, 
> dim);
> |               break;
> |     #define MAKE_INT_BRANCH(X) \
> |             case btyp_ ## X: \
> |               retval = argx.X ## _array_value ().nth_element (n, dim); \
> |               break
> |
> |             MAKE_INT_BRANCH (int8);
> |             MAKE_INT_BRANCH (int16);
> |             MAKE_INT_BRANCH (int32);
> |             MAKE_INT_BRANCH (int64);
> |             MAKE_INT_BRANCH (uint8);
> |             MAKE_INT_BRANCH (uint16);
> |             MAKE_INT_BRANCH (uint32);
> |             MAKE_INT_BRANCH (uint64);
> |     #undef MAKE_INT_BRANCH
> |             default:
> |               if (argx.is_cellstr ())
> |                 retval = argx.cellstr_value ().nth_element (n, dim);
> |               else
> |                 gripe_wrong_type_arg ("nth_element", argx);
> |             }
> |
> | This is from data.cc:6415 @ rev ec660526ae50.
> |
> | Can't this be improved? This manual polymorphism is error-prone
> | and ugly to read. Isn't there an abstract array type that one can
> | convert an octave_value into and then call virtual functions on
> | this type?
>
> I think the right thing to do is to change the above switch statement to
>
>  retval = argx.nth_element (n, dim);
>
> and then define
>
>  octave_value
>  octave_value::nth_element (const idx_vector& n, int dim) const
>  {
>    return rep->nth_element (n, dim);
>  }
[snip]
> I don't know of a simpler way to do this.

That's one thing I don't understand about octave_value. Doesn't this
seem like the wrong level of generality? An octave_value can also be a
function handle or a cell string. It seems wrong for those
octave_values to have an interface to all of these functions that
should only apply to numerical arrays. I wish there was an
intermediate type between octave_value and the numeric arrays that
Jaroslav is branching on... but perhaps that is too much work for no
real good reason.

> Mapper functions are similar, but reduce to repeated application of
> a simple non-member function. For those, we thought about doing the
> same as I outline above but decided to use a generic map function in
> the octave_value hierarchy and to switch on the type of map inside
> the map function for each specific value type (for example, see
> octave_matrix::map in ov-re-mat.cc).
>
> Maybe a similar strategy could be used for sum, cumsum, prod,
> cumprod, nth_element, etc. to abstract them all into one "reduction"
> function, but these functions ultimately call member functions, so
> I'm not sure how to handle that in a clean way with function
> pointers. Maybe there is a template trick I'm not seeing at the
> moment.

Isn't it just a matter of creating a friend reduction function, and
have that friend make the polymorphic calls through the rep pointer?

> How many of these functions are there that have this kind of switch
> statement?

It's probably not as many as I feared:

    address@hidden:~/coding/vcs/octave-devel$ grep -R 'define
MAKE_INT_BRANCH'  src/ liboctave/ | wc -l
    12

- Jordi G. H.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]