% -*- 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{Pair}
\label{sec:Pair}

VTK-m defines a \vtkm{Pair}\tparams{T1,T2} templated object that behaves just like \textcode{std:\colonhyp{}pair} from the standard template library.
The difference is that \vtkm{Pair} will work in both the execution and control environment, whereas the STL \textcode{std::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{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 Tags}
\label{sec:ListTags}

\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.

\VTKm uses a tag-based mechanism for defining lists, which differs significantly from lists in many other template metaprogramming libraries such as with \textcode{boost:\colonhyp{}mpl:\colonhyp{}vector} or \textcode{boost:\colonhyp{}vector}.
Rather than enumerating all list entries as template arguments, the list is referenced by a single tag class with a descriptive name.
The intention is to make fully resolved types shorter and more readable.
(Anyone experienced with template programming knows how insanely long and unreadable types can get in compiler errors and warnings.)

\subsection{Building List Tags}
\label{sec:BuildingListTags}

List tags are constructed in \VTKm by defining a \textcode{struct} that publicly inherits from another list tags.
The base list tags are defined in the \vtkmheader{vtkm}{ListTag.h} header.

The most basic list is defined with \vtkm{ListTagEmpty}.
This tag represents an empty list.

\vtkm{ListTagBase}\tparams{T, ...} represents a list of the types given as template parameters.
\vtkm{ListTagBase} supports a variable number of parameters with the maximum specified by \vtkmmacro{VTKM\_MAX\_BASE\_LIST}.

Finally, lists can be combined together with \vtkm{ListTagJoin}\tparams{ListTag1,ListTag2}, which concatinates two lists together.

The following example demonstrates how to build list tags using these base lists classes.
Note first that all the list tags are defined as \textcode{struct} rather than \textcode{class}.
Although these are roughly synonymous in C++, \textcode{struct} inheritance is by default public, and public inheritance is important for the list tags to work.
Note second that these tags are created by inheritance rather than using a type alias.
Although a type alias defined with \textcode{using} will work, it will lead to much uglier type names defined by the compiler.

\vtkmlisting{Creating list tags.}{BaseListTags.cxx}

\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}{TypeListTag.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{TypeListTagId}] Contains the single item \vtkm{Id}.
\item[\vtkm{TypeListTagId2}] Contains the single item \vtkm{Id2}.
\item[\vtkm{TypeListTagId3}] Contains the single item \vtkm{Id3}.
\item[\vtkm{TypeListTagIndex}] A list of all types used to index
  arrays. Contains \vtkm{Id}, \vtkm{Id2}, and \vtkm{Id3}.
\item[\vtkm{TypeListTagFieldScalar}] 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{TypeListTagFieldVec2}] A list containing types for values of
  fields with 2 dimensional vectors. All these vectors use floating point
  numbers.
\item[\vtkm{TypeListTagFieldVec3}] A list containing types for values of
  fields with 3 dimensional vectors. All these vectors use floating point
  numbers.
\item[\vtkm{TypeListTagFieldVec4}] A list containing types for values of
  fields with 4 dimensional vectors. All these vectors use floating point
  numbers.
\item[\vtkm{TypeListTagField}] A list containing all the types generally
  used for fields. It is the combination of \vtkm{TypeListTagFieldScalar},
  \vtkm{TypeListTagFieldVec2}, \vtkm{TypeListTagFieldVec3}, and
  \vtkm{TypeListTagFieldVec4}.
\item[\vtkm{TypeListTagScalarAll}] 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{TypeListTagVecCommon}] 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{TypeListTagVecAll}] A list of all \vtkm{Vec} classes with
  standard integers or floating points as components and lengths between 2
  and 4.
\item[\vtkm{TypeListTagAll}] A list of all types included in
  \vtkmheader{vtkm}{Types.h} with \vtkm{Vec}s with up to 4 components.
\item[\vtkm{TypeListTagCommon}] 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:BuildingListTags} as demonstrated in the following example.

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

The \vtkmheader{vtkm}{TypeListTag.h} header also defines a macro named \vtkmmacro{VTKM\_DEFAULT\_TYPE\_LIST\_TAG} 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\_TAG} 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\_TAG} macro.

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

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

\VTKm template metaprogramming lists are typically just passed to \VTKm
methods that internally operate on the lists. Although not typically used
outside of the \VTKm library, these operations are also available.

The \vtkmheader{vtkm}{ListTag.h} header comes with a \vtkm{ListForEach} function that takes a functor object and a list tag.
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|)}
