
[section:result_type Calculation of the Type of the Result]

The functions in this library are all overloaded to accept
mixed floating point (or mixed integer and floating point type)
arguments.  So for example:

   foo(1.0, 2.0);
   foo(1.0f, 2);
   foo(1.0, 2L);

etc, are all valid calls, as long as "foo" is a function taking two
floating-point arguments.  But that leaves the question:

[blurb ['"Given a special function with N arguments of
types T1, T2, T3 ... TN, then what type is the result?"]]

[*If all the arguments are of the same (floating point) type then the
result is the same type as the arguments.]

Otherwise, the type of the result
is computed using the following logic:

# Any arguments that are not template arguments are disregarded from
further analysis.
# For each type in the argument list, if that type is an integer type
then it is treated as if it were of type double for the purposes of
further analysis.
# If any of the arguments is a user-defined class type, then the result type
is the first such class type that is constructible from all of the other
argument types.
# If any of the arguments is of type `long double`, then the result is of type
`long double`.
# If any of the arguments is of type `double`, then the result is of type
`double`.
# Otherwise the result is of type `float`.

For example:

   cyl_bessel(2, 3.0);

Returns a `double` result, as does:

   cyl_bessel(2, 3.0f);

as in this case the integer first argument is treated as a `double` and takes
precedence over the `float` second argument.  To get a `float` result we would need
all the arguments to be of type float:

   cyl_bessel_j(2.0f, 3.0f);

When one or more of the arguments is not a template argument then it
doesn't effect the return type at all, for example:

   sph_bessel(2, 3.0f);

returns a `float`, since the first argument is not a template argument and
so doesn't effect the result: without this rule functions that take
explicitly integer arguments could never return `float`.

And for user-defined types, all of the following return an `NTL::RR` result:

   cyl_bessel_j(0, NTL::RR(2));

   cyl_bessel_j(NTL::RR(2), 3);

   cyl_bessel_j(NTL::quad_float(2), NTL::RR(3));

In the last case, `quad_float` is convertible to `RR`, but not vice-versa, so
the result will be an `NTL::RR`.  Note that this assumes that you are using
a [link math_toolkit.high_precision.use_ntl patched NTL library].

These rules are chosen to be compatible with the behaviour of
['ISO/IEC 9899:1999 Programming languages - C]
and with the
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf Draft Technical Report on C++ Library Extensions, 2005-06-24, section 5.2.1, paragraph 5].

[endsect]

[/
  Copyright 2006, 2012 John Maddock and Paul A. Bristow.
  Distributed under the Boost Software License, Version 1.0.
  (See accompanying file LICENSE_1_0.txt or copy at
  http://www.boost.org/LICENSE_1_0.txt).
]
