% -*- latex -*-

\chapter{Advanced Types}
\label{chap:AdvancedTypes}

Chapter \ref{chap:BaseTypes} introduced some of the base data types defined for use in \VTKm.
However, for simplicity Chapter \ref{chap:BaseTypes} just briefly touched the high-level concepts of these types.
In this chapter we dive into much greater depth and introduce several more types.


\section{Single Number Types}

As described in Chapter \ref{chap:BaseTypes}, \VTKm provides aliases for all the base C types to ensure the representation matches the variable use.
When a specific type width is not required, then the most common types to use are \vtkm{FloatDefault} for floating-point numbers, \vtkm{Id} for array and similar indices, and \vtkm{IdComponent} for shorter-width vector indices.

If a specific type width is desired, then one of the following is used to clearly declare the type and width.

\begin{minipage}{\textwidth}
  \centering
  \begin{tabular}{r@{\hskip 20pt}lll}
    bytes & floating point & signed integer & unsigned integer \\
    \hline
    1 &                & \vtkm{Int8}  & \vtkm{UInt8}  \\
    2 &                & \vtkm{Int16} & \vtkm{UInt16} \\
    4 & \vtkm{Float32} & \vtkm{Int32} & \vtkm{UInt32} \\
    8 & \vtkm{Float64} & \vtkm{Int64} & \vtkm{UInt64} \\
  \end{tabular}
\end{minipage}

These \VTKm--defined types should be preferred over basic C types like \textcode{int} or \textcode{float}.


\section{Vector Types}
\label{sec:AdvancedVectorTypes}

Visualization algorithms also often require operations on short vectors.
Arrays indexed in up to three dimensions are common.
Data are often defined in 2-space and 3-space, and transformations are typically done in homogeneous coordinates of length 4.
To simplify these types of operations, \VTKm provides the \vtkm{Vec}\tparams{T,Size} templated type, which is essentially a fixed length array of a given type.

The default constructor of \vtkm{Vec} objects leaves the values uninitialized.
All vectors have a constructor with one argument that is used to initialize
all components. All \vtkm{Vec} objects also have a constructor that allows you to
set the individual components (one per argument). All \vtkm{Vec} objects with a size
that is greater than 4 are constructed at run time and support an arbitrary number
of initial values. Likewise, there is a \vtkm{make\_Vec} convenience function
that builds initialized vector types with an arbitrary number of components.
Once created, you can use the bracket operator to get and set component values
with the same syntax as an array.

\vtkmlisting{Creating vector types.}{CreatingVectorTypes.cxx}

The types \vtkm{Id2}, \vtkm{Id3}, and \vtkm{Id4} are type aliases of \vtkm{Vec}\tparams{\vtkm{Id},2}, \vtkm{Vec}\tparams{\vtkm{Id},3}, and \vtkm{Vec}\tparams{\vtkm{Id},4}.
These are used to index arrays of 2, 3, and 4 dimensions, which is common.
Likewise, \vtkm{IdComponent2}, \vtkm{IdComponent4}, and \vtkm{IdComponent4} are type aliases of \vtkm{Vec}\tparams{\vtkm{IdComponent},2}, \vtkm{Vec}\tparams{\vtkm{IdComponent},3}, and \vtkm{Vec}\tparams{\vtkm{IdComponent},4}.

Because declaring \vtkm{Vec}\tparams{T,Size} with all of its template parameters can be cumbersome, \VTKm provides easy to use aliases for small vectors of base types.
As introduced in Section \ref{sec:VectorTypes}, the following type aliases are available.

\begin{minipage}{\textwidth}
  \centering
  \begin{tabular}{rr@{\hskip 20pt}lll}
    \multicolumn{2}{r@{\hskip 20pt}}{bytes size} & floating point & signed integer & unsigned integer \\
    \hline
    default
      & 2 & \vtkm{Vec2f}     & \vtkm{Vec2i}     & \vtkm{Vec2ui}     \\
      & 3 & \vtkm{Vec3f}     & \vtkm{Vec3i}     & \vtkm{Vec3ui}     \\
      & 4 & \vtkm{Vec4f}     & \vtkm{Vec4i}     & \vtkm{Vec4ui}     \\[3pt]
    1 & 2 &                  & \vtkm{Vec2i\_8}  & \vtkm{Vec2ui\_8}  \\
      & 3 &                  & \vtkm{Vec3i\_8}  & \vtkm{Vec3ui\_8}  \\
      & 4 &                  & \vtkm{Vec4i\_8}  & \vtkm{Vec4ui\_8}  \\[3pt]
    2 & 2 &                  & \vtkm{Vec2i\_16} & \vtkm{Vec2ui\_16} \\
      & 3 &                  & \vtkm{Vec3i\_16} & \vtkm{Vec3ui\_16} \\
      & 4 &                  & \vtkm{Vec4i\_16} & \vtkm{Vec4ui\_16} \\[3pt]
    4 & 2 & \vtkm{Vec2f\_32} & \vtkm{Vec2i\_32} & \vtkm{Vec2ui\_32} \\
      & 3 & \vtkm{Vec3f\_32} & \vtkm{Vec3i\_32} & \vtkm{Vec3ui\_32} \\
      & 4 & \vtkm{Vec4f\_32} & \vtkm{Vec4i\_32} & \vtkm{Vec4ui\_32} \\[3pt]
    8 & 2 & \vtkm{Vec2f\_64} & \vtkm{Vec2i\_64} & \vtkm{Vec2ui\_64} \\
      & 3 & \vtkm{Vec3f\_64} & \vtkm{Vec3i\_64} & \vtkm{Vec3ui\_64} \\
      & 4 & \vtkm{Vec4f\_64} & \vtkm{Vec4i\_64} & \vtkm{Vec4ui\_64} \\
  \end{tabular}
\end{minipage}

\vtkm{Vec} supports component-wise arithmetic using the operators for plus (\textcode{+}), minus (\textcode{-}), multiply (\textcode{*}), and divide (\textcode{/}).
It also supports scalar to vector multiplication with the multiply operator.
The comparison operators equal (\textcode{==}) is true if every pair of corresponding components are true and not equal (\textcode{!=}) is true otherwise.
A special \vtkm{Dot} function is overloaded to provide a dot product for every type of vector.

\vtkmlisting{Vector operations.}{VectorOperations.cxx}

These operators, of course, only work if they are also defined for the component type of the \vtkm{Vec}.
For example, the multiply operator will work fine on objects of type \vtkm{Vec}\tparams{char,3}, but the multiply operator will not work on objects of type \vtkm{Vec}\tparams{std::string,3} because you cannot multiply objects of type \textcode{std::string}.

In addition to generalizing vector operations and making arbitrarily long vectors, \vtkm{Vec} can be repurposed for creating any sequence of homogeneous objects.
Here is a simple example of using \vtkm{Vec} to hold the state of a polygon.

\vtkmlisting{Repurposing a \protect\vtkm{Vec}.}{EquilateralTriangle.cxx}

\index{Vec-like|(}

The \vtkm{Vec} class provides a convenient structure for holding and passing small vectors of data.
However, there are times when using \textidentifier{Vec} is inconvenient or inappropriate.
For example, the size of \vtkm{Vec} must be known at compile time, but there may be need for a vector whose size is unknown until compile time.
Also, the data populating a \vtkm{Vec} might come from a source that makes it inconvenient or less efficient to construct a \vtkm{Vec}.
For this reason, \VTKm also provides several \keyterm{\Veclike} objects that behave much like \vtkm{Vec} but are a different class.
These \Veclike objects have the same interface as \vtkm{Vec} except that the \textidentifier{NUM\_COMPONENTS} constant is not available on those that are sized at run time.
\Veclike objects also come with a \classmember*{Vec}{CopyInto} method that will take their contents and copy them into a standard \textidentifier{Vec} class.
(The standard \textidentifier{Vec} class also has a \classmember*{Vec}{CopyInto} method for consistency.)

The first \Veclike object is \vtkm{VecC}, which exposes a C-type array as a \textidentifier{Vec}.
The constructor for \vtkm{VecC} takes a C array and a size of that array.
There is also a constant version of \textidentifier{VecC} named \vtkm{VecCConst}, which takes a constant array and cannot be mutated.
The \vtkmheader{vtkm}{Types.h} header defines both \textidentifier{VecC} and \textidentifier{VecCConst} as well as multiple versions of \vtkm{make\_VecC} to easily convert a C array to either a \textidentifier{VecC} or \textidentifier{VecCConst}.

The following example demonstrates converting values from a constant table into a \vtkm{VecCConst} for further consumption.
The table and associated methods define how 8 points come together to form a hexahedron.

\vtkmlisting[ex:VecCConst]{Using \protect\vtkm{VecCConst} with a constant array.}{VecCExample.cxx}

\begin{commonerrors}
  The \vtkm{VecC} and \vtkm{VecCConst} classes only hold a pointer to a buffer that contains the data.
  They do not manage the memory holding the data.
  Thus, if the pointer given to \vtkm{VecC} or \vtkm{VecCConst} becomes invalid, then using the object becomes invalid.
  Make sure that the scope of the \vtkm{VecC} or \vtkm{VecCConst} does not outlive the scope of the data it points to.
\end{commonerrors}

The next \Veclike object is \vtkm{VecVariable}, which provides a \Veclike object that can be resized at run time to a maximum value.
Unlike \textidentifier{VecC}, \textidentifier{VecVariable} holds its own memory, which makes it a bit safer to use.
But also unlike \textidentifier{VecC}, you must define the maximum size of \textidentifier{VecVariable} at compile time.
Thus, \textidentifier{VecVariable} is really only appropriate to use when there is a predetermined limit to the vector size that is fairly small.

The following example uses a \vtkm{VecVariable} to store the trace of edges within a hexahedron.
This example uses the methods defined in Example~\ref{ex:VecCConst}.

\vtkmlisting{Using \protect\vtkm{VecVariable}.}{VecVariableExample.cxx}

\VTKm provides further examples of \Veclike objects as well.
For example, the \vtkm{VecFromPortal} and \vtkm{VecFromPortalPermute} objects allow you to treat a subsection of an arbitrarily large array as a \textidentifier{Vec}.
These objects work by attaching to array portals, which are described in Section~\ref{sec:ArrayPortals}.
Another example of a \Veclike object is \vtkm{VecRectilinearPointCoordinates}, which efficiently represents the point coordinates in an axis-aligned hexahedron.
Such shapes are common in structured grids.
These and other data sets are described in Chapter~\ref{chap:DataSets}.

\index{Vec-like|)}

\section{Range}
\label{sec:Range}

VTK-m provides a convenience structure named \vtkm{Range} to help manage a range of values.
The \textidentifier{Range} \textcode{struct} contains two data members, \classmember*{Range}{Min} and \classmember*{Range}{Max}, which represent the ends of the range of numbers.
\classmember*{Range}{Min} and \classmember*{Range}{Max} are both of type \vtkm{Float64}.
\classmember*{Range}{Min} and \classmember*{Range}{Max} can be directly accessed, but \textidentifier{Range} also comes with the following helper functions to make it easier to build and use ranges.
Note that all of these functions treat the minimum and maximum value as inclusive to the range.

\begin{description}
\item[{\classmember*{Range}{IsNonEmpty}}]
  Returns true if the range covers at least one value.
\item[{\classmember*{Range}{Contains}}]
  Takes a single number and returns true if that number is contained within the range.
\item[{\classmember*{Range}{Length}}]
  Returns the distance between \classmember*{Range}{Min} and \classmember*{Range}{Max}.
  Empty ranges return a length of 0.
  Note that if the range is non-empty and the length is 0, then \classmember*{Range}{Min} and \classmember*{Range}{Max} must be equal, and the range contains exactly one number.
\item[{\classmember*{Range}{Center}}]
  Returns the number equidistant to \classmember*{Range}{Min} and \classmember*{Range}{Max}.
  If the range is empty, NaN is returned.
\item[{\classmember*{Range}{Include}}]
  Takes either a single number or another range and modifies this range to include the given number or range.
  If necessary, the range is grown just enough to encompass the given argument.
  If the argument is already in the range, nothing changes.
\item[{\classmember*{Range}{Union}}]
  A nondestructive version of \classmember*{Range}{Include}, which builds a new \textidentifier{Range} that is the union of this range and the argument.
  The \textcode{+} operator is also overloaded to compute the union.
\end{description}

The following example demonstrates the operation of \vtkm{Range}.

\vtkmlisting{Using \protect\vtkm{Range}.}{UsingRange.cxx}

\section{Bounds}
\label{sec:Bounds}

VTK-m provides a convenience structure named \vtkm{Bounds} to help manage
an axis-aligned region in 3D space. Among other things, this structure is
often useful for representing a bounding box for geometry. The
\textidentifier{Bounds} \textcode{struct} contains three data members,
\classmember*{Bounds}{X}, \classmember*{Bounds}{Y}, and \classmember*{Bounds}{Z}, which represent the range of
the bounds along each respective axis. All three of these members are of
type \vtkm{Range}, which is discussed previously in
Section~\ref{sec:Range}. \classmember*{Bounds}{X}, \classmember*{Bounds}{Y}, and \classmember*{Bounds}{Z} can
be directly accessed, but \textidentifier{Bounds} also comes with the
following helper functions to make it easier to build and use ranges.

\begin{description}
\item[{\classmember*{Bounds}{IsNonEmpty}}]
  Returns true if the bounds cover at least one value.
\item[{\classmember*{Bounds}{Contains}}]
  Takes a \vtkm{Vec} of size 3 and returns true if those point coordinates are contained within the range.
\item[{\classmember*{Bounds}{Center}}]
  Returns the point at the center of the range as a \vtkm{Vec}\tparams{\vtkm{Float64},3}.
\item[{\classmember*{Bounds}{Include}}]
  Takes either a \vtkm{Vec} of size 3 or another bounds and modifies this bounds to include the given point or bounds.
  If necessary, the bounds are grown just enough to encompass the given argument.
  If the argument is already in the bounds, nothing changes.
\item[{\classmember*{Bounds}{Union}}]
  A nondestructive version of \classmember*{Bounds}{Include}, which builds a new \textidentifier{Bounds} that is the union of this bounds and the argument.
  The \textcode{+} operator is also overloaded to compute the union.
\end{description}

The following example demonstrates the operation of \vtkm{Bounds}.

\vtkmlisting{Using \protect\vtkm{Bounds}.}{UsingBounds.cxx}


\section{Traits}
\label{sec:Traits}

\index{traits|(}

When using templated types, it is often necessary to get information about the type or specialize code based on general properties of the type.
\VTKm uses \keyterm{traits} classes to publish and retrieve information about types.
A traits class is simply a templated structure that provides type aliases for tag\index{tag} structures, empty types used for identification.
The traits classes might also contain constant numbers and helpful static functions.
See {\it Effective C++ Third Edition} by Scott Mayers for a description of traits classes and their uses.

\subsection{Type Traits}

\index{traits!type|(}
\index{type traits|(}

The \vtkm{TypeTraits}\tparams{T} templated class provides basic information about a core type.
These type traits are available for all the basic C++ types as well as the core \VTKm types described in Chapter \ref{chap:BaseTypes}.
\vtkm{TypeTraits} contains the following elements.

\index{tag!type traits|(}

\begin{description}
\item[\classmember*{TypeTraits}{NumericTag}] \index{tag!numeric}
  This type is set to either \vtkm{TypeTraitsRealTag} or \vtkm{TypeTraitsIntegerTag} to signal that the type represents either floating point numbers or integers.
\item[\classmember*{TypeTraits}{DimensionalityTag}] \index{tag!dimensionality}
  This type is set to either \vtkm{TypeTraitsScalarTag} or \vtkm{TypeTraitsVectorTag} to signal that the type represents either a single scalar value or a tuple of values.
\item[\classmember*{TypeTraits}{ZeroInitialization}]
  A static member function that takes no arguments and returns 0 (or the closest equivalent to it) cast to the type.
\end{description}

The definition of \vtkm{TypeTraits} for \vtkm{Float32} could like something like this.
\vtkmlisting{Definition of \protect \vtkm{TypeTraits}\tparams{\protect \vtkm{Float32}}.}{TypeTraitsImpl.cxx}

Here is a simple example of using \vtkm{TypeTraits} to implement a generic function that behaves like the remainder operator (\textcode{\%}) for all types including floating points and vectors.

\vtkmlisting[ex:TypeTraits]{Using \textidentifier{TypeTraits} for a generic remainder.}{TypeTraits.cxx}

\index{tag!type traits|)}

\index{type traits|)}
\index{traits!type|)}


\subsection{Vector Traits}
\label{sec:VectorTraits}

\index{traits!vector|(}
\index{vector traits|(}

The templated \vtkm{Vec} class contains several items for introspection (such as the component type and its size).
However, there are other types that behave similarly to \textidentifier{Vec} objects but have different ways to perform this introspection.

\index{Vec-like} For example, \VTKm contains \Veclike objects that essentially behave the same but might have different features.
Also, there may be reason to interchangeably use basic scalar values, like an integer or floating point number, with vectors.
To provide a consistent interface to access these multiple types that represents vectors, the \vtkm{VecTraits}\tparams{T} templated class provides information and accessors to vector types.It contains the following elements.

\index{tag!vector traits|(}

\begin{description}
\item[\classmember*{VecTraits}{ComponentType}]
  This type is set to the type for each component in the vector.
  For example, a \vtkm{Id3} has \textidentifier{ComponentType} defined as \vtkm{Id}.
\item[\classmember*{VecTraits}{IsSizeStatic}]
  \index{tag!static vector size} \index{tag!variable vector size}
  This type is set to either \vtkm{VecTraitsTagSizeStatic} if the vector has a static number of components that can be determined at compile time or set to \vtkm{VecTraitsTagSizeVariable} if the size of the vector is determined at run time.
  If \textidentifier{IsSizeStatic} is set to \textidentifier{VecTraitsTagSizeVariable}, then \textidentifier{VecTraits} will be missing some information that cannot be determined at compile time.
\item[\classmember*{VecTraits}{HasMultipleComponents}] \index{tag!single component} \index{tag!multiple components}
  This type is set to either \vtkm{VecTraitsTagSingleComponent} if the vector length is size 1 or \vtkm{VecTraitsTagMultipleComponents} otherwise.
  This tag can be useful for creating specialized functions when a vector is really just a scalar.
  If the vector type is of variable size (that is, \textidentifier{IsSizeStatic} is \textidentifier{VecTraitsTagSizeVariable}), then \textidentifier{HasMultipleComponents} might be \textidentifier{VecTraitsTagMultipleComponents} even when at run time there is only one component.
\item[\classmember*{VecTraits}{NUM\_COMPONENTS}]
  An integer specifying how many components are contained in the vector.
  \textidentifier{NUM\_COMPONENTS} is not available for vector types of variable size (that is, \textidentifier{IsSizeStatic} is \textidentifier{VecTraitsTagSizeVariable}).
\item[\classmember*{VecTraits}{GetNumberOfComponents}]
  A static method that takes an instance of a vector and returns the number of components the vector contains.
  The result of \classmember*{VecTraits}{GetNumberOfComponents} is the same value of \textidentifier{NUM\_COMPONENTS} for vector types that have a static size (that is, \textidentifier{IsSizeStatic} is \textidentifier{VecTraitsTagSizeStatic}).
  But unlike \textidentifier{NUM\_COMPONENTS}, \classmember*{VecTraits}{GetNumberOfComponents} works for vectors of any type.
\item[\classmember*{VecTraits}{GetComponent}]
  A static method that takes a vector and returns a particular component.
\item[\classmember*{VecTraits}{SetComponent}]
  A static method that takes a vector and sets a particular component to a given value.
\item[\classmember*{VecTraits}{CopyInto}]
  A static method that copies the components of a vector to a \vtkm{Vec}.
\end{description}

The definition of \vtkm{VecTraits} for \vtkm{Id3} could look something like this.
\vtkmlisting{Definition of \protect \vtkm{VecTraits}\tparams{\protect \vtkm{Id3}}.}{VecTraitsImpl.cxx}

\index{tag!vector traits|)}

The real power of vector traits is that they simplify creating generic operations on any type that can look like a vector.
This includes operations on scalar values as if they were vectors of size one.
The following code uses vector traits to simplify the implementation of less functors\index{less} that define an ordering that can be used for sorting and other operations.

\vtkmlisting{Using \textidentifier{VecTraits} for less functors.}{VecTraits.cxx}

\index{vector traits|)}
\index{traits!vector|)}

\index{traits|)}


\section{List Templates}
\label{sec:ListTemplate}

\index{tag!lists|(}
\index{lists|(}

\index{template metaprogramming} \index{metaprogramming}
\VTKm internally uses template metaprogramming, which utilizes C++ templates to run source-generating programs, to customize code to various data and compute platforms.
One basic structure often uses with template metaprogramming is a list of class names (also sometimes called a tuple or vector, although both of those names have different meanings in \VTKm).

Many \VTKm users only need predefined lists, such as the type lists specified in Section~\ref{sec:TypeLists}.
Those users can skip most of the details of this section.
However, it is sometimes useful to modify lists, create new lists, or operate on lists, and these usages are documented here.

\subsection{Building Lists}
\label{sec:BuildingLists}

A basic list is defined with the \vtkm{List}\tparams{T, ...} template, which is defined in the \vtkmheader{vtkm}{List.h} header.
It is common (but not necessary) to use the \textcode{using} keyword to define an alias for a list with a particular meaning.

\vtkmlisting{Creating lists of types.}{BaseLists.cxx}

\VTKm defines the convenience class \vtkm{ListEmpty}, which is simply an empty list (i.e. \vtkm{List}\tparams{}).

\VTKm also provides a special identifier named \vtkm{ListUniversal}.
\textidentifier{ListUniversal} is a conceptual list containing all possible types.
Operations on \textidentifier{ListUniversal} will behave as if it contains all types where possible, but some operations (such as getting the size of the list) are ill-defined and will fail.

\subsection{Type Lists}
\label{sec:TypeLists}

\index{type lists|(}
\index{lists!types|(}
\index{tag!type lists|(}

One of the major use cases for template metaprogramming lists in \VTKm is to identify a set of potential data types for arrays.
The \vtkmheader{vtkm}{TypeList.h} header contains predefined lists for known VTK-m types.
Although technically all these lists are of C++ types, the types we refer to here are those data types stored in data arrays.
The following lists are provided.

\begin{description}
\item[\vtkm{TypeListId}] Contains the single item \vtkm{Id}.
\item[\vtkm{TypeListId2}] Contains the single item \vtkm{Id2}.
\item[\vtkm{TypeListId3}] Contains the single item \vtkm{Id3}.
\item[\vtkm{TypeListIdComponent}] Contains the single item \vtkm{IdComponent}.
\item[\vtkm{TypeListIndex}] A list of all types used to index
  arrays. Contains \vtkm{Id}, \vtkm{Id2}, and \vtkm{Id3}.
\item[\vtkm{TypeListFieldScalar}] A list containing types used for
  scalar fields. Specifically, it contains floating point numbers of
  different widths (i.e. \vtkm{Float32} and \vtkm{Float64}).
\item[\vtkm{TypeListFieldVec2}] A list containing types for values of
  fields with 2 dimensional vectors. All these vectors use floating point
  numbers.
\item[\vtkm{TypeListFieldVec3}] A list containing types for values of
  fields with 3 dimensional vectors. All these vectors use floating point
  numbers.
\item[\vtkm{TypeListFieldVec4}] A list containing types for values of
  fields with 4 dimensional vectors. All these vectors use floating point
  numbers.
\item[\vtkm{TypeListField}] A list containing all the types generally
  used for fields. It is the combination of \vtkm{TypeListFieldScalar},
  \vtkm{TypeListFieldVec2}, \vtkm{TypeListFieldVec3}, and
  \vtkm{TypeListFieldVec4}.
\item[\vtkm{TypeListScalarAll}] A list of all scalar types. It contains
  signed and unsigned integers of widths from 8 to 64 bits. It also
  contains floats of 32 and 64 bit widths.
\item[\vtkm{TypeListVecCommon}] A list of the most common vector
  types. It contains all \vtkm{Vec} class of size 2 through 4 containing
  components of unsigned bytes, signed 32-bit integers, signed 64-bit
  integers, 32-bit floats, or 64-bit floats.
\item[\vtkm{TypeListVecAll}] A list of all \vtkm{Vec} classes with
  standard integers or floating points as components and lengths between 2
  and 4.
\item[\vtkm{TypeListAll}] A list of all types included in
  \vtkmheader{vtkm}{Types.h} with \vtkm{Vec}s with up to 4 components.
\item[\vtkm{TypeListCommon}] A list containing only the most used types
  in visualization. This includes signed integers and floats that are 32 or
  64 bit. It also includes 3 dimensional vectors of floats. This is the
  default list used when resolving the type in variant arrays (described in
  Chapter~\ref{chap:VariantArrayHandle}).
\end{description}

If these lists are not sufficient, it is possible to build new type lists using the existing type lists and the list bases from Section~\ref{sec:BuildingLists} as demonstrated in the following example.

\vtkmlisting[ex:CustomTypeLists]{Defining new type lists.}{CustomTypeLists.cxx}

The \vtkmheader{vtkm}{TypeList.h} header also defines a macro named \vtkmmacro{VTKM\_DEFAULT\_TYPE\_LIST} that defines a default list of types to use in classes like \vtkmcont{VariantArrayHandle} (Chapter~\ref{chap:VariantArrayHandle}).
This list can be overridden by defining the \vtkmmacro{VTKM\_DEFAULT\_TYPE\_LIST} macro \emph{before} any \VTKm headers are included.
If included after a \VTKm header, the list is not likely to take effect.
Do not ignore compiler warnings about the macro being redefined, which you will not get if defined correctly.
Example~\ref{ex:CustomTypeLists} also contains an example of overriding the \vtkmmacro{VTKM\_DEFAULT\_TYPE\_LIST} macro.

\index{tag!type lists|)}
\index{lists!types|)}
\index{type lists|)}

\subsection{Querying Lists}
\label{sec:QueryingLists}

\vtkmheader{vtkm}{List.h} contains some templated classes to help get information about a list type.
This are particularly useful for lists that are provided as templated parameters for which you do not know the exact type.

The \vtkmmacro{VTKM\_IS\_LIST} does a compile-time check to make sure a particular type is actually a \vtkm{List} of types.
If the compile-time check fails, then a build error will occur.
This is a good way to verify that a templated class or method that expects a list actually gets a list.

\vtkmlisting{Checking that a template parameter is a valid \textidentifier{List}.}{VTKM_IS_LIST.cxx}

The size of a list can be determined by using the \vtkm{ListSize} template.
The type of the template will resolve to a \textcode{std::integral\_constant}\tparams{\vtkm{IdComponent},N} where \textcode{N} is the number of types in the list.
\vtkm{ListSize} does not work with \vtkm{ListUniversal}.

\vtkmlisting{Getting the size of a \textidentifier{List}.}{ListSize.cxx}

The \vtkm{ListHas} template can be used to determine if a \vtkm{List} contains a particular type.
\textidentifier{ListHas} takes two template parameters.
The first parameter is a form of \vtkm{List}.
The second parameter is any type to check to see if it is in the list.
If the type is in the list, then \textidentifier{ListHas} resolves to \textcode{std::true\_type}.
Otherwise it resolves to \textcode{std::false\_type}.
\vtkm{ListHas} always returns true for \vtkm{ListUniversal}.

\vtkmlisting{Determining if a \textidentifier{List} contains a particular type.}{ListHas.cxx}

The \vtkm{ListIndexOf} template can be used to get the index of a particular type in a \vtkm{List}.
\textidentifier{ListIndexOf} takes two template parameters.
The first parameter is a form of \vtkm{List}.
The second parameter is any type to check to see if it is in the list.
The type of the template will resolve to a \textcode{std::integral\_constant}\tparams{\vtkm{IdComponent},N} where \textcode{N} is the index of the type.
If the requested type is not in the list, then \textidentifier{ListIndexOf} becomes \textcode{std::integral\_constant}\tparams{\vtkm{IdComponent},-1}.

Conversely, the \vtkm{ListAt} template can be used to get the type for a particular index.
The two template parameters for \textidentifier{ListAt} are the \textidentifier{List} and an index for the list.

Neither \vtkm{ListIndexOf} nor \vtkm{ListAt} works with \vtkm{ListUniversal}.

\vtkmlisting{Using indices with \textidentifier{List}.}{ListIndices.cxx}

\subsection{Operating on Lists}
\label{sec:OperatingOnLists}

In addition to providing the base templates for defining and querying lists, \vtkmheader{vtkm}{List.h} also contains several features for operating on lists.

The \vtkm{ListAppend} template joins together 2 or more \textidentifier{List}s.
The items are concatinated in the order provided to \textidentifier{ListAppend}.
\textidentifier{ListAppend} does not work with \vtkm{ListUniversal}.

\vtkmlisting{Appending \textidentifier{List}s.}{ListAppend.cxx}

The \vtkm{ListIntersect} template takes two \textidentifier{List}s and becomes a \vtkm{List} containing all types in both lists.
If one of the lists is \vtkm{ListUniversal}, the contents of the other list used.

\vtkmlisting{Intersecting \textidentifier{List}s.}{ListIntersect.cxx}

The \vtkm{ListApply} template transfers all of the types in a \vtkm{List} to another template.
The first template argument of \textidentifier{ListApply} is the \textidentifier{List} to apply.
The second template argument is another template to apply to.
\textidentifier{ListApply} becomes an instance of the passed template with all the types in the \textidentifier{List}.
\textidentifier{ListApply} can be used to convert a \textidentifier{List} to some other template.
\textidentifier{ListApply} cannot be used with \vtkm{ListUniversal}.

\vtkmlisting{Applying a \textidentifier{List} to another template.}{ListApply.cxx}

The \vtkm{ListTransform} template applies each item in a \vtkm{List} to another template and constructs a list from all these applications.
The first template argument of \textidentifier{ListTransform} is the \textidentifier{List} to apply.
The second template argument is another template to apply to.
\textidentifier{ListTransform} becomes an instance of a new \vtkm{List} containing the passed template each type.
\textidentifier{ListTransform} cannot be used with \vtkm{ListUniversal}.

\vtkmlisting{Transforming a \textidentifier{List} using a custom template.}{ListTransform.cxx}

The \vtkm{ListRemoveIf} template removes items from a \vtkm{List} given a predicate.
The first template argument of \textidentifier{ListRemoveIf} is the \textidentifier{List}.
The second argument is another template that is used as a predicate to determine if the type should be removed or not.
The predicate should become a type with a \textcode{value} member that is a static true or false value.
Any type in the list that the predicate evaluates to true is removed.
\textidentifier{ListRemoveIf} cannot be used with \vtkm{ListUniversal}.

\vtkmlisting{Removing items from a \textidentifier{List}.}{ListRemoveIf.cxx}

The \vtkm{ListCross} takes two lists and performs a cross product of them.
It does this by creating a new \vtkm{List} that contains nested \textidentifier{List}s, each of length 2 and containing all possible pairs of items in the first list with items in the second list.
\textidentifier{ListCross} is often used in conjunction with another list processing command, such as \textidentifier{ListTransform} to build templated types of many combinations.
\textidentifier{ListCross} cannot be used with \vtkm{ListUniversal}.

\vtkmlisting{Creating the cross product of 2 \textidentifier{List}s.}{ListCross.cxx}

The \vtkm{ListForEach} function  takes a functor object and a \vtkm{List}.
It then calls the functor object with the default object of each type in the list.
This is most typically used with C++ run-time type information to convert a run-time polymorphic object to a statically typed (and possibly inlined) call.

The following example shows a rudimentary version of coverting a dynamically-typed array to a statically-typed array similar to what is done in \VTKm classes like \vtkmcont{VariantArrayHandle} (which is documented in Chapter~\ref{chap:VariantArrayHandle}).

\vtkmlisting{Converting dynamic types to static types with \textidentifier{ListForEach}.}{ListForEach.cxx}

\index{lists|)}
\index{tag!lists|)}


\section{Pair}
\label{sec:Pair}

VTK-m defines a \vtkm{Pair}\tparams{T1,T2} templated object that behaves just like \textcode{std:\colonhyp{}pair}\index{std::pair} from the standard template library.
The difference is that \vtkm{Pair} will work in both the execution and control environments, whereas the STL \textcode{std:\colonhyp{}pair} does not always work in the execution environment.

The VTK-m version of \vtkm{Pair} supports the same types, fields, and operations as the STL version.
VTK-m also provides a \vtkm{make\_Pair} function for convenience.


\section{Tuple}
\label{sec:Tuple}

\VTKm defines a \vtkm{Tuple} templated object that behaves like \textcode{std:\colonhyp{}tuple}\index{std::tuple} from the standard template library.
The main difference is that \vtkm{Tuple} will work in both the execution and control environments, whereas the STL \textcode{std:\colonhyp{}tuple} does not always work in the execution environment.

\subsection{Defining and Constructing}

\vtkm{Tuple} takes any number of template parameters that define the objects stored the tuple.

\vtkmlisting{Defining a \textidentifier{Tuple}.}{DefineTuple.cxx}

You can construct a \vtkm{Tuple} with arguments that will be used to initialize the respective objects.
As a convenience, you can use \vtkm{MakeTuple} to construct a \vtkm{Tuple} of types based on the arguments.

\vtkmlisting{Initializing values in a \textidentifier{Tuple}.}{InitTuple.cxx}

\subsection{Querying}

The size of a \vtkm{Tuple} can be determined by using the \vtkm{TupleSize} template, which resolves to an \textcode{std:\colonhyp{}integral\_constant}.
The types at particular indices can be determined with \vtkm{TupleElement}.

\vtkmlisting{Querying \textidentifier{Tuple} types.}{TupleQuery.cxx}

The function \vtkm{Get}\index{Tuple!Get} can be used to retrieve an element from the \vtkm{Tuple}.
\textidentifier{Get} returns a reference to the element, so you can set a \vtkm{Tuple} element by \textidentifier{Get}ing the value.

\vtkmlisting{Retrieving values from a \textidentifier{Tuple}.}{TupleGet.cxx}

\subsection{For Each}

\classmember{Tuple}{ForEach} is a method that takes a function or functor and calls it for each of the items in the tuple.
Nothing is returned from ForEach and any return value from the function is ignored.
\classmember*{Tuple}{ForEach} can be used to check the validity of each item.

\vtkmlisting{Using \textidentifier{Tuple}\textcode{::ForEach} to check the contents.}{TupleCheck.cxx}

\classmember{Tuple}{ForEach} can also be used to aggregate values.

\vtkmlisting{Using \textidentifier{Tuple}\textcode{::ForEach} to aggregate.}{TupleAggregate.cxx}

\subsection{Transform}

\classmember{Tuple}{Transform} is a method that builds a new Tuple by calling a function or functor on each of the items.
The return value is placed in the corresponding part of the resulting Tuple, and the type is automatically created from the return type of the function.

\vtkmlisting{Transforming a \textidentifier{Tuple}.}{TupleTransform.cxx}

\subsection{Apply}

\classmember{Tuple}{Apply} is a method that calls a function or functor using the objects in the Tuple as the arguments.
If the function returns a value, that value is returned from Apply.

\vtkmlisting{Applying a \textidentifier{Tuple} as arguments to a function.}{TupleApply.cxx}

If additional arguments are given to \classmember*{Tuple}{Apply}, they are also passed to the function (before the objects in the \vtkm{Tuple}).
This is helpful for passing state to the function.

\vtkmlisting{Using extra arguments with \textidentifier{Tuple}\textcode{::Apply}.}{TupleApplyExtraArgs.cxx}


\section{Error Codes}
\label{sec:ErrorCodes}
\label{sec:ErrorCode}

\index{error codes|(}

For operations that occur in the control environment, \VTKm uses exceptions to report errors as described in Chapter \ref{chap:ErrorHandlingControl}.
However, when operating in the execution environment, it is not feasible to throw exceptions. Thus, for operations designed for the execution environment, the status of an operation that can fail is returned as an \vtkm{ErrorCode}, which is an \textcode{enum}.
An \textidentifier{ErrorCode} can be one of the following enumerators.

\begin{description}
\item[\classmember{ErrorCode}{Success}]
  The operation completed successfully.
\item[\classmember{ErrorCode}{InvalidShapeId}]
  An operation on a cell was given a shape identifier that is not recognized.
\item[\classmember{ErrorCode}{InvalidNumberOfPoints}]
  The wrong number of points was provided for a given cell type.
  For example, if a triangle has 4 points associated with it, you are likely to get this error.
%% \item[\classmember{ErrorCode}{WrongShapeIdForTagType}]
%%   An internal error from the lightweight cell library.
\item[\classmember{ErrorCode}{InvalidPointId}]
  A bad point identifier was detected while operating on a cell.
\item[\classmember{ErrorCode}{InvalidEdgeId}]
  A bad edge identifier was detected while operating on a cell.
\item[\classmember{ErrorCode}{InvalidFaceId}]
  A bad face identifier was detected while operating on a cell.
\item[\classmember{ErrorCode}{SolutionDidNotConverge}]
  An iterative operation did not find an appropriate solution.
  The result is not likely to be accurate.
\item[\classmember{ErrorCode}{MatrixFactorizationFailed}]
  A solution was not found for a linear system.
\item[\classmember{ErrorCode}{DegenerateCellDetected}]
  A cell's parameters have degenerated it to another type.
  For example, if two vertices of a tetrahedron are the same, it degenerates into a triangle.
\item[\classmember{ErrorCode}{MalformedCellDetected}]
  The structure of a cell is incorrect.
  For example, if the vertices of a cell are listed in the wrong order, you might encounter this error.
\item[\classmember{ErrorCode}{OperationOnEmptyCell}]
  There is an ``empty'' cell placeholder type to be used when other cell types cannot be applied.
  Because it is a placeholder, operations on these types of cells are undefined.
\item[\classmember{ErrorCode}{CellNotFound}]
  A locate operation failed to find a cell given the search criteria.
\end{description}

If a function or method returns an \textidentifier{ErrorCode}, it is a good practice to check to make sure that the returned value is \classmember*{ErrorCode}{Success}.
If it is not, you can use the \vtkm{ErrorString} function to convert the \textidentifier{ErrorCode} to a descriptive C string.
The easiest thing to do from within a worklet is to call the worklet's \classmember*{FunctorBase}{RaiseError} method.

\vtkmlisting{Checking an \textidentifier{ErrorCode} and reporting errors in a worklet.}{HandleErrorCode.cxx}

\index{error codes|)}
