1++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 Problem with ``is_writable`` and ``is_swappable`` in N1550_ 3++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 5.. _N1550: http://www.boost-consulting.com/writing/n1550.html 6.. _N1530: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1530.html 7 8:Author: David Abrahams and Jeremy Siek 9:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu 10:Organization: `Boost Consulting`_, Indiana University Bloomington 11:date: $Date$ 12:Copyright: Copyright David Abrahams, Jeremy Siek 2003. Use, modification and 13 distribution is subject to the Boost Software License, 14 Version 1.0. (See accompanying file LICENSE_1_0.txt or copy 15 at http://www.boost.org/LICENSE_1_0.txt) 16 17.. _`Boost Consulting`: http://www.boost-consulting.com 18 19.. contents:: Table of Contents 20 21============== 22 Introduction 23============== 24 25The ``is_writable`` and ``is_swappable`` traits classes in N1550_ 26provide a mechanism for determining at compile time if an iterator 27type is a model of the new Writable Iterator and Swappable Iterator 28concepts, analogous to ``iterator_traits<X>::iterator_category`` 29for the old iterator concepts. For backward compatibility, 30``is_writable`` and ``is_swappable`` not only work with new 31iterators, but they also are intended to work for old 32iterators (iterators that meet the requirements for one of the 33iterator concepts in the current standard). In the case of old 34iterators, the writability and swapability is deduced based on the 35``iterator_category`` and also the ``reference`` type. The 36specification for this deduction gives false positives for forward 37iterators that have non-assignable value types. 38 39To review, the part of the ``is_writable`` trait definition which 40applies to old iterators is:: 41 42 if (cat is convertible to output_iterator_tag) 43 return true; 44 else if (cat is convertible to forward_iterator_tag 45 and iterator_traits<Iterator>::reference is a 46 mutable reference) 47 return true; 48 else 49 return false; 50 51Suppose the ``value_type`` of the iterator ``It`` has a private 52assignment operator:: 53 54 class B { 55 public: 56 ... 57 private: 58 B& operator=(const B&); 59 }; 60 61and suppose the ``reference`` type of the iterator is ``B&``. In 62that case, ``is_writable<It>::value`` will be true when in fact 63attempting to write into ``B`` will cause an error. 64 65The same problem applies to ``is_swappable``. 66 67 68==================== 69 Proposed Resolution 70==================== 71 721. Remove the ``is_writable`` and ``is_swappable`` traits, and remove the 73 requirements in the Writable Iterator and Swappable Iterator concepts 74 that require their models to support these traits. 75 762. Change the ``is_readable`` specification to be: 77 ``is_readable<X>::type`` is ``true_type`` if the 78 result type of ``X::operator*`` is convertible to 79 ``iterator_traits<X>::value_type`` and is ``false_type`` 80 otherwise. Also, ``is_readable`` is required to satisfy 81 the requirements for the UnaryTypeTrait concept 82 (defined in the type traits proposal). 83 84 Remove the requirement for support of the ``is_readable`` trait from 85 the Readable Iterator concept. 86 87 883. Remove the ``iterator_tag`` class. 89 904. Change the specification of ``traversal_category`` to:: 91 92 traversal-category(Iterator) = 93 let cat = iterator_traits<Iterator>::iterator_category 94 if (cat is convertible to incrementable_iterator_tag) 95 return cat; // Iterator is a new iterator 96 else if (cat is convertible to random_access_iterator_tag) 97 return random_access_traversal_tag; 98 else if (cat is convertible to bidirectional_iterator_tag) 99 return bidirectional_traversal_tag; 100 else if (cat is convertible to forward_iterator_tag) 101 return forward_traversal_tag; 102 else if (cat is convertible to input_iterator_tag) 103 return single_pass_iterator_tag; 104 else if (cat is convertible to output_iterator_tag) 105 return incrementable_iterator_tag; 106 else 107 return null_category_tag; 108 109 110========== 111 Rationale 112========== 113 1141. There are two reasons for removing ``is_writable`` 115 and ``is_swappable``. The first is that we do not know of 116 a way to fix the specification so that it gives the correct 117 answer for all iterators. Second, there was only a weak 118 motivation for having ``is_writable`` and ``is_swappable`` 119 there in the first place. The main motivation was simply 120 uniformity: we have tags for the old iterator categories 121 so we should have tags for the new iterator categories. 122 While having tags and the capability to dispatch based 123 on the traversal categories is often used, we see 124 less of a need for dispatching based on writability 125 and swappability, since typically algorithms 126 that need these capabilities have no alternative if 127 they are not provided. 128 1292. We discovered that the ``is_readable`` trait can be implemented 130 using only the iterator type itself and its ``value_type``. 131 Therefore we remove the requirement for ``is_readable`` from the 132 Readable Iterator concept, and change the definition of 133 ``is_readable`` so that it works for any iterator type. 134 1353. The purpose of the ``iterator_tag`` class was to 136 bundle the traversal and access category tags 137 into the ``iterator_category`` typedef. 138 With ``is_writable`` and ``is_swappable`` gone, and 139 ``is_readable`` no longer in need of special hints, 140 there is no reason for iterators to provide 141 information about the access capabilities of an iterator. 142 Thus there is no need for the ``iterator_tag``. The 143 traversal tag can be directly used for the 144 ``iterator_category``. If a new iterator is intended to be backward 145 compatible with old iterator concepts, a tag type 146 that is convertible to both one of the new traversal tags 147 and also to an old iterator tag can be created and use 148 for the ``iterator_category``. 149 1504. The changes to the specification of ``traversal_category`` are a 151 direct result of the removal of ``iterator_tag``. 152 153