@@ -39,9 +39,90 @@ to unordered associative containers as well.
39
39
Set priority to 3 after reflector poll.
40
40
</p >
41
41
42
+ <note >2024-12-04; Jonathan provides wording</note >
43
+ <p >
44
+ If we want to require <a href =" https://www.stroustrup.com/SCARY.pdf" >SCARY</a >
45
+ iterators then that should be a proposal that goes through LEWG design review.
46
+ I propose an almost minimal change to make the spec consistent without
47
+ imposing any new requirements on implementations.
48
+ </p >
49
+ <p >
50
+ The minimal change would be to say that iterators remain valid if `a` and `a2`
51
+ have the same type, which is the minimum portable guarantee that always holds.
52
+ However what matters in practice is whether the iterator types are the same.
53
+ That would not be a portable guarantee, because it depends on whether the
54
+ implementation uses SCARY iterators for its maps and sets, so users could
55
+ write code that works on one implementation and fails to compile when moved
56
+ to a different implementation. But that portability trap would be present
57
+ even if we only say iterators remain valid when `a` and `a2` are the same type.
58
+ If the code compiles and works on an implementation with SCARY iterators,
59
+ then users will rely on that, even if unintentionally. Leaving that case
60
+ unspecified or undefined in the standard doesn't prevent users from relying
61
+ on it. It doesn't seem to serve any benefit to pretend it doesn't work when
62
+ it actually does on some implementations.
63
+ </p >
64
+ <p >
65
+ N.B. Libstdc++ associative container iterators are SCARY by default,
66
+ but non-SCARY when `-D_GLIBCXX_DEBUG` is used to enable Debug Mode
67
+ (see <a href =" https://gcc.gnu.org/PR62169" >Bug 62169</a >).
68
+ I believe libc++ iterators are SCARY even when
69
+ `-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_DEBUG` is used,
70
+ and MSVC STL iterators are SCARY even when `/D_ITERATOR_DEBUG_LEVEL` is used.
71
+ </p >
72
+
42
73
</discussion >
43
74
44
75
<resolution >
76
+ <p >
77
+ This wording is relative to <paper num =" N4993" />.
78
+ </p >
79
+
80
+ <ol >
81
+ <li >
82
+ <p >
83
+ Modify <sref ref =" [associative.reqmts.general]" /> as indicated:
84
+ </p >
85
+
86
+ <blockquote >
87
+ <pre ><code >a.merge(a2)</code ></pre >
88
+ <p >-112-
89
+ <i >Result</i >: `void`
90
+ </p >
91
+ <p >-113-
92
+ <i >Preconditions</i >:
93
+ `a.get_allocator() == a2.get_allocator()`<ins > is `true`</ins >.
94
+ </p >
95
+ <p >-114-
96
+ <i >Effects</i >:
97
+ Attempts to extract each element in `a2` and insert it into `a`
98
+ using the comparison object of `a`.
99
+ In containers with unique keys,
100
+ if there is an element in `a` with key equivalent to
101
+ the key of an element from `a2`,
102
+ then that element is not extracted from `a2`.
103
+ </p >
104
+ <p >-115-
105
+ <i >Postconditions</i >:
106
+ Pointers and references to the transferred elements of `a2`
107
+ refer to those same elements but as members of `a`.
108
+ <ins >If `a.begin()` and `a2.begin()` have the same type, iterators</ins >
109
+ <del >Iterators</del >
110
+ referring to the transferred elements will continue to refer to their elements,
111
+ but they now behave as iterators into `a`, not into `a2`.
112
+ </p >
113
+ <p >-116-
114
+ <i >Throws</i >:
115
+ Nothing unless the comparison objects throws.
116
+ </p >
117
+ <p >-117-
118
+ <i >Complexity</i >:
119
+ <i >N</i > log(`a.size()`+<i >N</i >), where <i >N</i > has the value `a2.size()`.
120
+ </p >
121
+
122
+ </blockquote >
123
+ </li >
124
+ </ol >
125
+
45
126
</resolution >
46
127
47
128
</issue >
0 commit comments