lines 9-126 of file: include/cppad/core/base_cond_exp.hpp

{xrst_begin base_cond_exp}

Base Type Requirements for Conditional Expressions
##################################################

Purpose
*******
These definitions are required by the user's code to support the
``AD`` < *Base* > type for :ref:`CondExp-name` operations:

CompareOp
*********
The following ``enum`` type is used in the specifications below:
::

   namespace CppAD {
   // The conditional expression operator enum type
   enum CompareOp
   {  CompareLt, // less than
   CompareLe, // less than or equal
   CompareEq, // equal
   CompareGe, // greater than or equal
   CompareGt, // greater than
   CompareNe  // not equal
   };
   }

CondExpTemplate
***************
The type *Base* must support the syntax

| |tab| *result* = ``CppAD::CondExpOp`` (
| |tab| |tab| *cop* , *left* , *right* , *exp_if_true* , *exp_if_false*
| |tab| )

which computes implements the corresponding :ref:`CondExp-name`
function when the result has prototype

   *Base* *result*

The argument *cop* has prototype

   ``enum CppAD::CompareOp`` *cop*

The other arguments have the prototype

| |tab| ``const`` *Base* & *left*
| |tab| ``const`` *Base* & *right*
| |tab| ``const`` *Base* & *exp_if_true*
| |tab| ``const`` *Base* & *exp_if_false*

Ordered Type
============
If *Base* is a relatively simple type
that supports
``<`` , ``<=`` , ``==`` , ``>=`` , and ``>`` operators
its ``CondExpOp`` function can be defined by

| ``namespace CppAD`` {
| |tab| ``inline`` *Base* ``CondExpOp`` (
| |tab| ``enum CppAD::CompareOp`` *cop*             ,
| |tab| ``const`` *Base* & *left*           ,
| |tab| ``const`` *Base* & *right*          ,
| |tab| ``const`` *Base* & *exp_if_true*    ,
| |tab| ``const`` *Base* & *exp_if_false*   )
| |tab| { ``return CondExpTemplate`` (
| |tab| |tab| |tab| ``cop`` , ``left`` , ``right`` , ``trueCase`` , ``falseCase`` );
| |tab| }
| }

For example, see
:ref:`double CondExpOp<base_alloc.hpp@CondExpOp>` .
For an example of and implementation of ``CondExpOp`` with
a more involved *Base* type see
:ref:`adolc CondExpOp<base_adolc.hpp@CondExpOp>` .

Not Ordered
===========
If the type *Base* does not support ordering,
the ``CondExpOp`` function does not make sense.
In this case one might (but need not) define ``CondExpOp`` as follows:

| ``namespace CppAD`` {
| |tab| ``inline`` *Base* ``CondExpOp`` (
| |tab| ``enum CompareOp`` *cop*            ,
| |tab| ``const`` *Base* & *left*          ,
| |tab| ``const`` *Base* & *right*         ,
| |tab| ``const`` *Base* & *exp_if_true*   ,
| |tab| ``const`` *Base* & *exp_if_false*  )
| |tab| {  // ``attempt to use CondExp with a`` *Base* ``argument``
| |tab| |tab| ``assert`` (0);
| |tab| |tab| ``return`` *Base* (0);
| |tab| }
| }

For example, see
:ref:`complex CondExpOp<base_complex.hpp@CondExpOp>` .

CondExpRel
**********
The macro invocation

   ``CPPAD_COND_EXP_REL`` ( *Base* )

uses ``CondExpOp`` above to define the following functions

| |tab| ``CondExpLt`` ( *left* , *right* , *exp_if_true* , *exp_if_false* )
| |tab| ``CondExpLe`` ( *left* , *right* , *exp_if_true* , *exp_if_false* )
| |tab| ``CondExpEq`` ( *left* , *right* , *exp_if_true* , *exp_if_false* )
| |tab| ``CondExpGe`` ( *left* , *right* , *exp_if_true* , *exp_if_false* )
| |tab| ``CondExpGt`` ( *left* , *right* , *exp_if_true* , *exp_if_false* )

where the arguments have type *Base* .
This should be done inside of the CppAD namespace.
For example, see
:ref:`base_alloc<base_alloc.hpp@CondExpRel>` .

{xrst_end base_cond_exp}
