forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			138 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
			
		
		
	
	
			138 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
| .. index:: Use-Auto Transform
 | |
| 
 | |
| ==================
 | |
| Use-Auto Transform
 | |
| ==================
 | |
| 
 | |
| The Use-Auto Transform is responsible for using the ``auto`` type specifier for
 | |
| variable declarations to *improve code readability and maintainability*. The
 | |
| transform is enabled with the :option:`-use-auto` option of
 | |
| :program:`cpp11-migrate`. 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 transform 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``.
 | |
| 
 | |
| Known Limitations
 | |
| =================
 | |
| * If the initializer is an explicit conversion constructor, the transform will
 | |
|   not replace the type specifier even though it would be safe to do so.
 | |
| * User-defined iterators are not handled at this time.
 |