Boost logo

Boost Users :

From: Matt Calabrese (mcalabre_at_[hidden])
Date: 2004-03-14 07:58:43


Sorry if this is a double post, new to this.

> Besides this issue, AFAIK these are already usable. Of course, if you
> would like to improve them/contribute more optimal/clean/better in any
> other regard implementation, please do.
>
> No, please go ahead! Cavalry have enough on their plates already (among
> other things, a new version of the library is upcoming, with plenty of
> new exciting and useful stuff like associative sequences), so progress
> on these two is totally in your hands.
>
> --
> Aleksey Gurtovoy
> MetaCommunications Engineering

Okay, I decided before I continue with my other library, I'll fully
implement rational_c properly (and possibly fixed_c), however, doing so
without making the code horribly complex would require changes to the
current definitions of pretty much all of the operations (plus, multiplies,
etc. as well as the conditional operators).

The problem is that those current functions take 5 parameters, making
specialization nearly impossible for the rational and fixed templates as
you'd have to account for when the 3rd, 4th, 5th, etc parameters are not
passed (and so the default integral 0 is used). That can't be easily done
(at least I don't see how) without having to specialize each condition
separately (one for 3 rational types, one for 4 rational types, etc ).
Moreso, this applies to the conditional operators as well, there is no easy
way to account for using different types in multiplies IE multiplying a
rational and integral together, or a fixed and rational, etc. Again, to
account for these possibilities you'd have to make an incredibly large
amount of specializations. Of course, you could always just limit them to
only work when all the parameters are the same kind of compile-time value
template, but that would be somewhat limitting,especially with other
solutions available.

What I propose is a way around this situation, but still have the
metafunctions declared the same way, therefore not breaking old code and not
limiting functionality. To do so, the following adjustments would have to be
made (and I have already begun to make them for my own use):

1) Additional versions of all of the arithmetic operators which take 2
parameters, each need to be defined and work like binary operators. They
should be specialized for when both the left and right operands are of the
same type. How to account for when they are different types will be covered
in the future points.
2) A value_cast metafunction which can cast between all different
compile-time constant types. The way it is implemented is by requiring all
types to have specialized metafunctions for converting to and from the fixed
point type. When value_cast is used, it, by default, converts the right hand
operand to fixed_c, then converts that fixed_c to the target type. Since a
fixed_c can hold pretty much any real value to a certain precision, you can
be certain, to an extent, that little, if any precision will be lost through
conversion. So, with that proposed addition, you'd be able to convert
between all different types and only require people developing new types to
have to specialize conversion to and from fixed_c. The only problem is that
in order for the value_cast to exist, it obviously needs to have a parameter
which specifies a type to convert to. The only way I can currently see that
would allow that would be to have the value_cast take a type parameter which
would be a template instantiation with a dummy value, which would, in a way,
be very similar to rebinding allocators.
3) The conditional operations and 2 operand arithmetic operations should be
redefined in the base template definition to convert both types to fixed_c
and then make a comaprison, therefore allowing programmers to use the
operations on two different types of compile-time constants without having
to manually convert them to similar types before-hand (as I alluded in first
point). The conditional operations can then be specialized for when the
types are the same on each side to avoid the cost of a cast on each of the
operands to fixed_c.
4) The current "varying length" operations which cause problems (multiplies,
plus, minus, etc) should be redefined to just call the 2 operand version of
the corresponding operation on each of the parameters passed to the
operation. This way, programmers can still pass multiple parameters to these
functions, with each parameter being a different type, without the developer
having to make an extremely large amount of specializations for each type
(including those which have yet to be developed).

I have already begun implementing all of the points I have suggested, though
with my rational_c as a the basis for conversion rather than fixed_c (as I
haven't yet developed fixed_c). Also, converting to and from rational_c is
considerably simpler than converting to and from fixed_c. For this reason, I
may end up leaving the basis for conversion as rational_c instead of
fixed_c.

If anyone sees any other, more elegant solutions for the problems I
mentioned, please post them and I may change my approach. Additional
suggestions are also greatly appreciated.

Thanks.

-Matt Calabrese


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net