.. title:: clang-tidy - modernize-use-auto

modernize-use-auto
==================

This check is responsible for using the ``auto`` type specifier for variable
declarations to *improve code readability and maintainability*. For example:

.. code-block:: c++

  std::vector<int>::iterator I = my_container.begin();

  // transforms to:

  auto I = my_container.begin();

The ``auto`` type specifier will only be introduced in situations where the
variable type matches the type of the initializer expression. In other words
``auto`` should deduce the same type that was originally spelled in the source.
However, not every situation should be transformed:

.. code-block:: c++

  int val = 42;
  InfoStruct &I = SomeObject.getInfo();

  // Should not become:

  auto val = 42;
  auto &I = SomeObject.getInfo();

In this example using ``auto`` for builtins doesn't improve readability. In
other situations it makes the code less self-documenting impairing readability
and maintainability. As a result, ``auto`` is used only introduced in specific
situations described below.

Iterators
---------

Iterator type specifiers tend to be long and used frequently, especially in
loop constructs. Since the functions generating iterators have a common format,
the type specifier can be replaced without obscuring the meaning of code while
improving readability and maintainability.

.. code-block:: c++

  for (std::vector<int>::iterator I = my_container.begin(),
                                  E = my_container.end();
       I != E; ++I) {
  }

  // becomes

  for (auto I = my_container.begin(), E = my_container.end(); I != E; ++I) {
  }

The check will only replace iterator type-specifiers when all of the following
conditions are satisfied:

* The iterator is for one of the standard container in ``std`` namespace:

  * ``array``
  * ``deque``
  * ``forward_list``
  * ``list``
  * ``vector``
  * ``map``
  * ``multimap``
  * ``set``
  * ``multiset``
  * ``unordered_map``
  * ``unordered_multimap``
  * ``unordered_set``
  * ``unordered_multiset``
  * ``queue``
  * ``priority_queue``
  * ``stack``

* The iterator is one of the possible iterator types for standard containers:

  * ``iterator``
  * ``reverse_iterator``
  * ``const_iterator``
  * ``const_reverse_iterator``

* In addition to using iterator types directly, typedefs or other ways of
  referring to those types are also allowed. However, implementation-specific
  types for which a type like ``std::vector<int>::iterator`` is itself a
  typedef will not be transformed. Consider the following examples:

.. code-block:: c++

  // The following direct uses of iterator types will be transformed.
  std::vector<int>::iterator I = MyVec.begin();
  {
    using namespace std;
    list<int>::iterator I = MyList.begin();
  }

  // The type specifier for J would transform to auto since it's a typedef
  // to a standard iterator type.
  typedef std::map<int, std::string>::const_iterator map_iterator;
  map_iterator J = MyMap.begin();

  // The following implementation-specific iterator type for which
  // std::vector<int>::iterator could be a typedef would not be transformed.
  __gnu_cxx::__normal_iterator<int*, std::vector> K = MyVec.begin();

* The initializer for the variable being declared is not a braced initializer
  list. Otherwise, use of ``auto`` would cause the type of the variable to be
  deduced as ``std::initializer_list``.

New expressions
---------------

Frequently, when a pointer is declared and initialized with ``new``, the
pointee type is written twice: in the declaration type and in the
``new`` expression. In this cases, the declaration type can be replaced with
``auto`` improving readability and maintainability.

.. code-block:: c++

  TypeName *my_pointer = new TypeName(my_param);

  // becomes

  auto *my_pointer = new TypeName(my_param);

The check will also replace the declaration type in multiple declarations, if
the following conditions are satisfied:

* All declared variables have the same type (i.e. all of them are pointers to
  the same type).
* All declared variables are initialized with a ``new`` expression.
* The types of all the new expressions are the same than the pointee of the
  declaration type.

.. code-block:: c++

  TypeName *my_first_pointer = new TypeName, *my_second_pointer = new TypeName;

  // becomes

  auto *my_first_pointer = new TypeName, *my_second_pointer = new TypeName;

Cast expressions
----------------

Frequently, when a variable is declared and initialized with a cast, the
variable type is written twice: in the declaration type and in the
cast expression. In this cases, the declaration type can be replaced with
``auto`` improving readability and maintainability.

.. code-block:: c++

  TypeName *my_pointer = static_cast<TypeName>(my_param);

  // becomes

  auto *my_pointer = static_cast<TypeName>(my_param);

The check handles ``static_cast``, ``dynamic_cast``, ``const_cast``,
``reinterpret_cast``, functional casts, C-style casts and function templates
that behave as casts, such as ``llvm::dyn_cast``, ``boost::lexical_cast`` and
``gsl::narrow_cast``.  Calls to function templates are considered to behave as
casts if the first template argument is explicit and is a type, and the function
returns that type, or a pointer or reference to it.

Known Limitations
-----------------

* If the initializer is an explicit conversion constructor, the check will not
  replace the type specifier even though it would be safe to do so.

* User-defined iterators are not handled at this time.

Options
-------

.. option:: MinTypeNameLength

   If the option is set to non-zero (default `5`), the check will ignore type
   names having a length less than the option value. The option affects
   expressions only, not iterators.
   Spaces between multi-lexeme type names (``long int``) are considered as one.
   If ``RemoveStars`` option (see below) is set to non-zero, then ``*s`` in
   the type are also counted as a part of the type name.

.. code-block:: c++

  // MinTypeNameLength = 0, RemoveStars=0

  int a = static_cast<int>(foo());            // ---> auto a = ...
  // length(bool *) = 4
  bool *b = new bool;                         // ---> auto *b = ...
  unsigned c = static_cast<unsigned>(foo());  // ---> auto c = ...

  // MinTypeNameLength = 5, RemoveStars=0

  int a = static_cast<int>(foo());                 // ---> int  a = ...
  bool b = static_cast<bool>(foo());               // ---> bool b = ...
  bool *pb = static_cast<bool*>(foo());            // ---> bool *pb = ...
  unsigned c = static_cast<unsigned>(foo());       // ---> auto c = ...
  // length(long <on-or-more-spaces> int) = 8
  long int d = static_cast<long int>(foo());       // ---> auto d = ...

  // MinTypeNameLength = 5, RemoveStars=1

  int a = static_cast<int>(foo());                 // ---> int  a = ...
  // length(int * * ) = 5
  int **pa = static_cast<int**>(foo());            // ---> auto pa = ...
  bool b = static_cast<bool>(foo());               // ---> bool b = ...
  bool *pb = static_cast<bool*>(foo());            // ---> auto pb = ...
  unsigned c = static_cast<unsigned>(foo());       // ---> auto c = ...
  long int d = static_cast<long int>(foo());       // ---> auto d = ...

.. option:: RemoveStars

   If the option is set to non-zero (default is `0`), the check will remove
   stars from the non-typedef pointer types when replacing type names with
   ``auto``. Otherwise, the check will leave stars. For example:

.. code-block:: c++

  TypeName *my_first_pointer = new TypeName, *my_second_pointer = new TypeName;

  // RemoveStars = 0

  auto *my_first_pointer = new TypeName, *my_second_pointer = new TypeName;

  // RemoveStars = 1

  auto my_first_pointer = new TypeName, my_second_pointer = new TypeName;
