This adds a pair of Swift protocols that represents C++ iterator types conforming to `std::contiguous_iterator_tag` requirements. These are random access iterators that guarantee that the values are stored in consequent memory addresses.
This will be used to optimize usage of C++ containers such as `std::vector` from Swift, for instance, by providing an overload of `withContiguousStorageIfAvailable` for contiguous containers.
rdar://137877849
This cleans up the C++ iteration tests and makes sure that we test the setup where a C++ iterator and a C++ collection are defined in different Clang modules.
When importing a C++ class template instantiation, Swift translates the template parameter type names from C++ into their Swift equivalent.
For instance, `basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t>>` gets imported as `basic_string<Scalar, char_traits<Scalar>, allocator<Scalar>>`: `wchar_t` is imported as `CWideChar`, which is a typealias for `Scalar` on most platforms including Darwin. Notice that Swift goes through the `CWideChar` typealias on the specific platform. Another instantiation `basic_string<uint32_t, char_traits<uint32_t>, allocator<uint32_t>>` also gets imported as `basic_string<Scalar, char_traits<Scalar>, allocator<Scalar>>`: `uint32_t` is also imported as `Scalar`. This is problematic because we have two distinct C++ types that have the same name in Swift.
This change makes sure Swift doesn't go through typealiases when emitting names of template parameters, so `wchar_t` would now get printed as `CWideChar`, `int` would get printed as `CInt`, etc.
This also encourages clients to use the correct type (`CInt`, `CWideChar`, etc) instead of relying on platform-specific typealiases.
rdar://115673622
This will be used to provide a safe overload of `std::vector::erase` in Swift.
`std::vector::erase` is not currently imported into Swift because it returns a C++ iterator.
rdar://113704853
I discovered this when experimenting with `std::map::iterator`, which has a const overload of `operator*` that returns a non-const reference, and does not have a const overload of `operator*`.
rdar://112471779
This is an inheritor of the existing `UnsafeCxxInputIterator` protocol, with the only difference being the ability to mutate `var pointee` via a non-const `operator*()`.
This is needed to support mutable subscripts for `std::map` via `CxxDictionary`.
rdar://105399019
C++ `T& operator*()` is mapped to a Swift computed property `var pointee: T`.
Previously `var pointee` only had a getter, after this change it will also have a setter if the C++ type declares an overload of `operator*` that returns a mutable reference.
rdar://112471779
This fixes the automatic `std::unordered_map` conformance to CxxDictionary on Linux. Previously `std::unordered_map::const_iterator` was not auto-conformed to UnsafeCxxInputIterator because its `operator==` is defined on a templated base class of `const_iterator`.
rdar://105220600
C++ iterator types are often templated, and sometimes declare `operator==` as a non-member templated function. In libc++, an example of this is `__wrap_iter` which is used as an iterator type for `std::vector` and `std::string`.
We don't currently import templated non-member operators into Swift, however, we still want to support common C++ iterator patterns.
This change adds logic to instantiate templated non-member `operator==` for types that define `iterator_category` and are therefore likely to be valid iterator types.
rdar://97915515
If an operator is declared as a method of a templated class, we were failing to look it up during auto-conformance to `UnsafeCxxInputIterator`.
This fixes `Interop/Cxx/stdlib/use-std-map.swift` on Ubuntu.
rdar://102420290
This became an issue in rebranch: multiple interop tests started failing (e.g. `Interop/Cxx/foreign-reference/pod.swift`).
The problem is not specific to rebranch though.
rdar://102151836
This makes ClangImporter automatically conform C++ sequence types to `Cxx.UnsafeCxxInputIterator` protocol.
We consider a C++ type to be a random access iterator type if conforms to `UnsafeCxxInputIterator`, and additionally defines `operator-` and `operator+=`.
This lifts the requirement for the user to explicitly add `import Cxx` in Swift code that relies on protocols from the `Cxx` module, such as `CxxSequence`.
These errors were sometimes produced when synthesizing conformance to `UnsafeCxxInputIterator`:
```
<unknown>:0: error: circular reference
<unknown>:0: note: through reference here
<unknown>:0: note: through reference here
```
This happened because `NominalTypeDecl::lookupDirect` attempts to deserialize Swift extensions of the type, which might belong to the module which has a dependency to the module that is currently being imported, which leads to deserialization errors.
This change makes sure we don't call `NominalTypeDecl::lookupDirect` when synthesizing conformances for C++ types.
Previosly we didn't detect `func ==` that was declared out-of-class when synthesizing conformaces to `UnsafeCxxInputIterator`. Now we do.
rdar://96235368
This teaches ClangImporter to synthesize conformances of C++ iterator types to `UnsafeCxxInputIterator` protocol from the `Cxx` module.
We consider a C++ type to be an iterator if it defines a subtype (usually a typedef or a using decl) called `iterator_category` that inherits from `std::input_iterator_tag`.
rdar://96235368