.. note::

   For ArborX 1.x, see
   :doc:`ArborX::AccessTraits (v1) </API-Reference/v1/v1-ArborX%3A%3AAccessTraits>`


``AccessTraits``
================
Defined in header `<ArborX_AccessTraits.hpp> <https://github.com/arborx/ArborX/blob/master/src/spatial/detail/ArborX_AccessTraits.hpp>`_

``ArborX::AccessTraits`` is a customization point, not a class to instantiate.
It tells the spatial index constructor (e.g.,
:cpp:func:`BoundingVolumeHierarchy constructor <BoundingVolumeHierarchy::BoundingVolumeHierarchy>`)
how much data to index and how to access that data, or a spatial index query
(e.g., :cpp:func:`BoundingVolumeHierarchy::query`)
what predicates to query for.

ArborX does not implement :cpp:struct:`AccessTraits` for arbitrary types.
To pass your own data container ``T`` to a constructor or to ``query()``,
specialize ``ArborX::AccessTraits<T>`` and provide the members listed below.
ArborX only provides specializations for Kokkos views
(see :ref:`Provided specializations <accesstraits-provided-specializations>`).

.. note::

   The declaration below documents the requirements a specialization must
   satisfy. It is not the declaration of a primary template with these members.
   The primary template in the header is an empty stub, only used to diagnose
   missing specializations at compile time.

.. cpp:struct:: template <typename T, typename Enable = void> AccessTraits

   Requirements on a specialization ``AccessTraits<T>``.

   :tparam T: User data container.
   :tparam Enable: Always ``void`` in a user specialization of ``AccessTraits<T>``.
      It exists to allow constrained partial specializations
      (e.g., with ``std::enable_if`` or ``requires``).

   .. cpp:type:: memory_space

      Must name a valid Kokkos memory space in which the data resides.

   .. cpp:function:: KOKKOS_FUNCTION static auto size(T const& data)

      :param data: Data argument passed to the spatial index constructor or ``query()``.
      :return: The number of values (primitives or predicates).
         The return type must be an integral type.

   .. cpp:function:: KOKKOS_FUNCTION static decltype(auto) get(T const& data, decltype(size(data)) i)

      :param data: Data argument passed to the spatial index constructor or ``query()``.
      :param i: Position of the value to return.
      :return: The ``i``-th value. The return type must not be ``void``.

      If ``T`` is passed to a constructor, the return type must decay to the
      ``Value`` template argument of the spatial index.

      If ``T`` is passed to ``query()``, the return type must decay to a valid
      ArborX predicate, e.g., one generated by
      :cpp:func:`nearest` or
      :cpp:func:`intersects`.

      It must be callable from the device, which means it needs to be marked
      with the ``KOKKOS_FUNCTION`` macro.

.. _accesstraits-provided-specializations:

Provided specializations
------------------------
ArborX provides partial specializations for Kokkos views of rank 1 and 2.

.. cpp:struct:: template <typename View> requires(Kokkos::is_view_v<View> && View::rank() == 1) AccessTraits<View>

   :cpp:func:`AccessTraits::get` returns a const reference to the element ``v(i)``.
   :cpp:type:`AccessTraits::memory_space` is the memory space of the view.

.. cpp:struct:: template <typename View> requires(Kokkos::is_view_v<View> && View::rank() == 2) AccessTraits<View>

   :cpp:func:`AccessTraits::get` returns by value the ``ArborX::Point``
   built from the coordinates ``v(i, 0)``, ``v(i, 1)``, ... in row ``i``.
   A statically known second extent determines the dimension of the point;
   for a dynamic second extent, a three-dimensional point is built from the
   first three columns.
   :cpp:type:`AccessTraits::memory_space` is the memory space of the view.


Example
-------
The example below specializes :cpp:struct:`AccessTraits` for two user types:
``PointCloud``, passed to the constructor of the ``BoundingVolumeHierarchie``
spatial index to provide the points, and ``Spheres``, passed to ``query()`` to
provide the predicates.

.. literalinclude:: ../../../examples/access_traits/example_cuda_access_traits.cpp
   :language: C++
   :lines: 11-

See ``examples/access_traits/example_host_access_traits.cpp`` for an example
of an :cpp:struct:`AccessTraits` specialization for host data (``std::vector``).
