mirror of
				https://github.com/saitohirga/WSJT-X.git
				synced 2025-10-30 20:40:28 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			153 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
			
		
		
	
	
			153 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 | |
|  Problem with ``is_writable`` and ``is_swappable`` in N1550_
 | |
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 | |
| 
 | |
| .. _N1550: http://www.boost-consulting.com/writing/n1550.html
 | |
| .. _N1530: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1530.html
 | |
| 
 | |
| :Author: David Abrahams and Jeremy Siek
 | |
| :Contact: dave@boost-consulting.com, jsiek@osl.iu.edu
 | |
| :Organization: `Boost Consulting`_, Indiana University Bloomington
 | |
| :date: $Date$
 | |
| :Copyright: Copyright David Abrahams, Jeremy Siek 2003. Use, modification and
 | |
|       distribution is subject to the Boost Software License,
 | |
|       Version 1.0. (See accompanying file LICENSE_1_0.txt or copy
 | |
|       at http://www.boost.org/LICENSE_1_0.txt)
 | |
| 
 | |
| .. _`Boost Consulting`: http://www.boost-consulting.com
 | |
| 
 | |
| .. contents:: Table of Contents
 | |
| 
 | |
| ==============
 | |
|  Introduction
 | |
| ==============
 | |
| 
 | |
| The ``is_writable`` and ``is_swappable`` traits classes in N1550_
 | |
| provide a mechanism for determining at compile time if an iterator
 | |
| type is a model of the new Writable Iterator and Swappable Iterator
 | |
| concepts, analogous to ``iterator_traits<X>::iterator_category``
 | |
| for the old iterator concepts. For backward compatibility,
 | |
| ``is_writable`` and ``is_swappable`` not only work with new
 | |
| iterators, but they also are intended to work for old
 | |
| iterators (iterators that meet the requirements for one of the
 | |
| iterator concepts in the current standard). In the case of old
 | |
| iterators, the writability and swapability is deduced based on the
 | |
| ``iterator_category`` and also the ``reference`` type. The
 | |
| specification for this deduction gives false positives for forward
 | |
| iterators that have non-assignable value types.
 | |
| 
 | |
| To review, the part of the ``is_writable`` trait definition which
 | |
| applies to old iterators is::
 | |
| 
 | |
|   if (cat is convertible to output_iterator_tag)
 | |
|       return true;
 | |
|   else if (cat is convertible to forward_iterator_tag
 | |
|            and iterator_traits<Iterator>::reference is a 
 | |
|                mutable reference)
 | |
|       return true;
 | |
|   else
 | |
|       return false;
 | |
| 
 | |
| Suppose the ``value_type`` of the iterator ``It`` has a private
 | |
| assignment operator::
 | |
| 
 | |
|   class B {
 | |
|   public:
 | |
|     ...
 | |
|   private:
 | |
|     B& operator=(const B&);
 | |
|   };
 | |
| 
 | |
| and suppose the ``reference`` type of the iterator is ``B&``.  In
 | |
| that case, ``is_writable<It>::value`` will be true when in fact
 | |
| attempting to write into ``B`` will cause an error.
 | |
| 
 | |
| The same problem applies to ``is_swappable``.
 | |
| 
 | |
| 
 | |
| ====================
 | |
|  Proposed Resolution
 | |
| ====================
 | |
| 
 | |
| 1. Remove the ``is_writable`` and ``is_swappable`` traits, and remove the
 | |
|    requirements in the Writable Iterator and Swappable Iterator concepts
 | |
|    that require their models to support these traits.
 | |
| 
 | |
| 2. Change the ``is_readable`` specification to be:
 | |
|    ``is_readable<X>::type`` is ``true_type`` if the
 | |
|    result type of ``X::operator*`` is convertible to
 | |
|    ``iterator_traits<X>::value_type`` and is ``false_type``
 | |
|    otherwise. Also, ``is_readable`` is required to satisfy
 | |
|    the requirements for the UnaryTypeTrait concept
 | |
|    (defined in the type traits proposal).
 | |
|    
 | |
|    Remove the requirement for support of the ``is_readable`` trait from
 | |
|    the Readable Iterator concept.
 | |
| 
 | |
| 
 | |
| 3. Remove the ``iterator_tag`` class.
 | |
| 
 | |
| 4. Change the specification of ``traversal_category`` to::
 | |
| 
 | |
|     traversal-category(Iterator) =
 | |
|         let cat = iterator_traits<Iterator>::iterator_category
 | |
|         if (cat is convertible to incrementable_iterator_tag)
 | |
|           return cat; // Iterator is a new iterator
 | |
|         else if (cat is convertible to random_access_iterator_tag)
 | |
|             return random_access_traversal_tag;
 | |
|         else if (cat is convertible to bidirectional_iterator_tag)
 | |
|             return bidirectional_traversal_tag;
 | |
|         else if (cat is convertible to forward_iterator_tag)
 | |
|             return forward_traversal_tag;
 | |
|         else if (cat is convertible to input_iterator_tag)
 | |
|             return single_pass_iterator_tag;
 | |
|         else if (cat is convertible to output_iterator_tag)
 | |
|             return incrementable_iterator_tag;
 | |
|         else
 | |
|             return null_category_tag;
 | |
| 
 | |
| 
 | |
| ==========
 | |
|  Rationale
 | |
| ==========
 | |
| 
 | |
| 1. There are two reasons for removing ``is_writable``
 | |
|    and ``is_swappable``. The first is that we do not know of
 | |
|    a way to fix the specification so that it gives the correct
 | |
|    answer for all iterators. Second, there was only a weak
 | |
|    motivation for having ``is_writable`` and ``is_swappable``
 | |
|    there in the first place.  The main motivation was simply
 | |
|    uniformity: we have tags for the old iterator categories
 | |
|    so we should have tags for the new iterator categories.
 | |
|    While having tags and the capability to dispatch based
 | |
|    on the traversal categories is often used, we see
 | |
|    less of a need for dispatching based on writability
 | |
|    and swappability, since typically algorithms
 | |
|    that need these capabilities have no alternative if
 | |
|    they are not provided.
 | |
| 
 | |
| 2. We discovered that the ``is_readable`` trait can be implemented
 | |
|    using only the iterator type itself and its ``value_type``.
 | |
|    Therefore we remove the requirement for ``is_readable`` from the
 | |
|    Readable Iterator concept, and change the definition of
 | |
|    ``is_readable`` so that it works for any iterator type.
 | |
| 
 | |
| 3. The purpose of the ``iterator_tag`` class was to
 | |
|    bundle the traversal and access category tags
 | |
|    into the ``iterator_category`` typedef.
 | |
|    With ``is_writable`` and ``is_swappable`` gone, and
 | |
|    ``is_readable`` no longer in need of special hints,
 | |
|    there is no reason for iterators to provide
 | |
|    information about the access capabilities of an iterator.
 | |
|    Thus there is no need for the ``iterator_tag``. The
 | |
|    traversal tag can be directly used for the
 | |
|    ``iterator_category``. If a new iterator is intended to be backward
 | |
|    compatible with old iterator concepts, a tag type
 | |
|    that is convertible to both one of the new traversal tags 
 | |
|    and also to an old iterator tag can be created and use
 | |
|    for the ``iterator_category``.
 | |
| 
 | |
| 4. The changes to the specification of ``traversal_category`` are a 
 | |
|    direct result of the removal of ``iterator_tag``.
 | |
| 
 |