#ifndef TEST_INTEROP_CXX_STDLIB_INPUTS_CUSTOM_ITERATOR_H #define TEST_INTEROP_CXX_STDLIB_INPUTS_CUSTOM_ITERATOR_H #include #include // MARK: Valid iterator types struct ConstIterator { private: int value; public: using iterator_category = std::input_iterator_tag; using value_type = int; using pointer = int *; using reference = const int &; using difference_type = int; ConstIterator(int value) : value(value) {} ConstIterator(const ConstIterator &other) = default; const int &operator*() const { return value; } ConstIterator &operator++() { value++; return *this; } ConstIterator operator++(int) { auto tmp = ConstIterator(value); value++; return tmp; } bool operator==(const ConstIterator &other) const { return value == other.value; } bool operator!=(const ConstIterator &other) const { return value != other.value; } }; struct ConstRACIterator { private: const int *value; public: using iterator_category = std::random_access_iterator_tag; using value_type = int; using pointer = int *; using reference = const int &; using difference_type = int; ConstRACIterator(const int *value) : value(value) {} ConstRACIterator(const ConstRACIterator &other) = default; const int &operator*() const { return *value; } ConstRACIterator &operator++() { value++; return *this; } ConstRACIterator operator++(int) { auto tmp = ConstRACIterator(value); value++; return tmp; } void operator+=(difference_type v) { value += v; } void operator-=(difference_type v) { value -= v; } ConstRACIterator operator+(difference_type v) const { return ConstRACIterator(value + v); } ConstRACIterator operator-(difference_type v) const { return ConstRACIterator(value - v); } friend ConstRACIterator operator+(difference_type v, const ConstRACIterator &it) { return it + v; } int operator-(const ConstRACIterator &other) const { return value - other.value; } bool operator<(const ConstRACIterator &other) const { return value < other.value; } bool operator==(const ConstRACIterator &other) const { return value == other.value; } bool operator!=(const ConstRACIterator &other) const { return value != other.value; } }; // Same as ConstRACIterator, but operator+= returns a reference to this. struct ConstRACIteratorRefPlusEq { private: const int *value; public: using iterator_category = std::random_access_iterator_tag; using value_type = int; using pointer = int *; using reference = const int &; using difference_type = int; ConstRACIteratorRefPlusEq(const int *value) : value(value) {} ConstRACIteratorRefPlusEq(const ConstRACIteratorRefPlusEq &other) = default; const int &operator*() const { return *value; } ConstRACIteratorRefPlusEq &operator++() { value++; return *this; } ConstRACIteratorRefPlusEq operator++(int) { auto tmp = ConstRACIteratorRefPlusEq(value); value++; return tmp; } ConstRACIteratorRefPlusEq &operator+=(difference_type v) { value += v; return *this; } ConstRACIteratorRefPlusEq &operator-=(difference_type v) { value -= v; return *this; } ConstRACIteratorRefPlusEq operator+(difference_type v) const { return ConstRACIteratorRefPlusEq(value + v); } ConstRACIteratorRefPlusEq operator-(difference_type v) const { return ConstRACIteratorRefPlusEq(value - v); } friend ConstRACIteratorRefPlusEq operator+(difference_type v, const ConstRACIteratorRefPlusEq &it) { return it + v; } int operator-(const ConstRACIteratorRefPlusEq &other) const { return value - other.value; } bool operator<(const ConstRACIteratorRefPlusEq &other) const { return value < other.value; } bool operator==(const ConstRACIteratorRefPlusEq &other) const { return value == other.value; } bool operator!=(const ConstRACIteratorRefPlusEq &other) const { return value != other.value; } }; /// Same as ConstIterator, but defines `operator==` as a non-member. struct ConstIteratorOutOfLineEq { int value; using iterator_category = std::input_iterator_tag; using value_type = int; using pointer = int *; using reference = int &; using difference_type = int; ConstIteratorOutOfLineEq(int value) : value(value) {} ConstIteratorOutOfLineEq(const ConstIteratorOutOfLineEq &other) = default; const int &operator*() const { return value; } ConstIteratorOutOfLineEq &operator++() { value++; return *this; } ConstIteratorOutOfLineEq operator++(int) { auto tmp = ConstIteratorOutOfLineEq(value); value++; return tmp; } }; bool operator==(const ConstIteratorOutOfLineEq &lhs, const ConstIteratorOutOfLineEq &rhs) { return lhs.value == rhs.value; } bool operator!=(const ConstIteratorOutOfLineEq &lhs, const ConstIteratorOutOfLineEq &rhs) { return lhs.value != rhs.value; } /// Only satisfies the minimal requirements for an iterator. struct MinimalIterator { int value; using iterator_category = std::input_iterator_tag; const int &operator*() const { return value; } MinimalIterator &operator++() { value++; return *this; } bool operator==(const MinimalIterator &other) const { return value == other.value; } }; struct ForwardIterator { int value; using iterator_category = std::forward_iterator_tag; using reference = const int &; const int &operator*() const { return value; } ForwardIterator &operator++() { value++; return *this; } ForwardIterator operator++(int) { ForwardIterator tmp = {value}; value++; return tmp; } bool operator==(const ForwardIterator &other) const { return value == other.value; } }; struct HasCustomIteratorTag { struct CustomTag : public std::input_iterator_tag {}; int value; using iterator_category = CustomTag; const int &operator*() const { return value; } HasCustomIteratorTag &operator++() { value++; return *this; } bool operator==(const HasCustomIteratorTag &other) const { return value == other.value; } }; struct HasCustomRACIteratorTag { struct CustomTag : public std::random_access_iterator_tag {}; int value; using iterator_category = CustomTag; const int &operator*() const { return value; } HasCustomRACIteratorTag &operator++() { value++; return *this; } void operator+=(int x) { value += x; } int operator-(const HasCustomRACIteratorTag &x) const { return value - x.value; } bool operator==(const HasCustomRACIteratorTag &other) const { return value == other.value; } }; struct HasCustomInheritedRACIteratorTag { struct CustomTag0 : public std::random_access_iterator_tag {}; using CustomTag1 = CustomTag0; struct CustomTag2 : public CustomTag1 {}; using CustomTag3 = CustomTag2; using CustomTag4 = CustomTag3; int value; using iterator_category = CustomTag4; const int &operator*() const { return value; } HasCustomInheritedRACIteratorTag &operator++() { value++; return *this; } void operator+=(int x) { value += x; } int operator-(const HasCustomInheritedRACIteratorTag &x) const { return value - x.value; } bool operator==(const HasCustomInheritedRACIteratorTag &other) const { return value == other.value; } }; struct HasCustomIteratorTagInline { struct iterator_category : public std::input_iterator_tag {}; int value; const int &operator*() const { return value; } HasCustomIteratorTagInline &operator++() { value++; return *this; } bool operator==(const HasCustomIteratorTagInline &other) const { return value == other.value; } }; struct HasTypedefIteratorTag { int value; typedef std::input_iterator_tag iterator_category; const int &operator*() const { return value; } HasTypedefIteratorTag &operator++() { value++; return *this; } bool operator==(const HasTypedefIteratorTag &other) const { return value == other.value; } }; struct MutableRACIterator { private: int *value; public: struct iterator_category : std::random_access_iterator_tag, std::output_iterator_tag {}; using value_type = int; using pointer = int *; using reference = const int &; using difference_type = int; MutableRACIterator(int *value) : value(value) {} MutableRACIterator(const MutableRACIterator &other) = default; const int &operator*() const { return *value; } int &operator*() { return *value; } MutableRACIterator &operator++() { value++; return *this; } MutableRACIterator operator++(int) { auto tmp = MutableRACIterator(value); value++; return tmp; } void operator+=(difference_type v) { value += v; } void operator-=(difference_type v) { value -= v; } MutableRACIterator operator+(difference_type v) const { return MutableRACIterator(value + v); } MutableRACIterator operator-(difference_type v) const { return MutableRACIterator(value - v); } friend MutableRACIterator operator+(difference_type v, const MutableRACIterator &it) { return it + v; } int operator-(const MutableRACIterator &other) const { return value - other.value; } bool operator<(const MutableRACIterator &other) const { return value < other.value; } bool operator==(const MutableRACIterator &other) const { return value == other.value; } bool operator!=(const MutableRACIterator &other) const { return value != other.value; } }; #if __cplusplus >= 202002L struct ConstContiguousIterator { private: const int *value; public: using iterator_category = std::random_access_iterator_tag; using iterator_concept = std::contiguous_iterator_tag; using value_type = int; using pointer = int *; using reference = const int &; using difference_type = int; ConstContiguousIterator(const int *value) : value(value) {} ConstContiguousIterator(const ConstContiguousIterator &other) = default; const int &operator*() const { return *value; } ConstContiguousIterator &operator++() { value++; return *this; } ConstContiguousIterator operator++(int) { auto tmp = ConstContiguousIterator(value); value++; return tmp; } void operator+=(difference_type v) { value += v; } void operator-=(difference_type v) { value -= v; } ConstContiguousIterator operator+(difference_type v) const { return ConstContiguousIterator(value + v); } ConstContiguousIterator operator-(difference_type v) const { return ConstContiguousIterator(value - v); } friend ConstContiguousIterator operator+(difference_type v, const ConstContiguousIterator &it) { return it + v; } int operator-(const ConstContiguousIterator &other) const { return value - other.value; } bool operator<(const ConstContiguousIterator &other) const { return value < other.value; } bool operator==(const ConstContiguousIterator &other) const { return value == other.value; } bool operator!=(const ConstContiguousIterator &other) const { return value != other.value; } }; struct HasCustomContiguousIteratorTag { private: const int *value; public: struct CustomTag : std::contiguous_iterator_tag {}; using iterator_category = std::random_access_iterator_tag; using iterator_concept = CustomTag; using value_type = int; using pointer = int *; using reference = const int &; using difference_type = int; HasCustomContiguousIteratorTag(const int *value) : value(value) {} HasCustomContiguousIteratorTag(const HasCustomContiguousIteratorTag &other) = default; const int &operator*() const { return *value; } HasCustomContiguousIteratorTag &operator++() { value++; return *this; } HasCustomContiguousIteratorTag operator++(int) { auto tmp = HasCustomContiguousIteratorTag(value); value++; return tmp; } void operator+=(difference_type v) { value += v; } void operator-=(difference_type v) { value -= v; } HasCustomContiguousIteratorTag operator+(difference_type v) const { return HasCustomContiguousIteratorTag(value + v); } HasCustomContiguousIteratorTag operator-(difference_type v) const { return HasCustomContiguousIteratorTag(value - v); } friend HasCustomContiguousIteratorTag operator+(difference_type v, const HasCustomContiguousIteratorTag &it) { return it + v; } int operator-(const HasCustomContiguousIteratorTag &other) const { return value - other.value; } bool operator<(const HasCustomContiguousIteratorTag &other) const { return value < other.value; } bool operator==(const HasCustomContiguousIteratorTag &other) const { return value == other.value; } bool operator!=(const HasCustomContiguousIteratorTag &other) const { return value != other.value; } }; struct MutableContiguousIterator { private: int *value; public: using iterator_category = std::random_access_iterator_tag; using iterator_concept = std::contiguous_iterator_tag; using value_type = int; using pointer = int *; using reference = const int &; using difference_type = int; MutableContiguousIterator(int *value) : value(value) {} MutableContiguousIterator(const MutableContiguousIterator &other) = default; const int &operator*() const { return *value; } int &operator*() { return *value; } MutableContiguousIterator &operator++() { value++; return *this; } MutableContiguousIterator operator++(int) { auto tmp = MutableContiguousIterator(value); value++; return tmp; } void operator+=(difference_type v) { value += v; } void operator-=(difference_type v) { value -= v; } MutableContiguousIterator operator+(difference_type v) const { return MutableContiguousIterator(value + v); } MutableContiguousIterator operator-(difference_type v) const { return MutableContiguousIterator(value - v); } friend MutableContiguousIterator operator+(difference_type v, const MutableContiguousIterator &it) { return it + v; } int operator-(const MutableContiguousIterator &other) const { return value - other.value; } bool operator<(const MutableContiguousIterator &other) const { return value < other.value; } bool operator==(const MutableContiguousIterator &other) const { return value == other.value; } bool operator!=(const MutableContiguousIterator &other) const { return value != other.value; } }; /// This is actually just a random access iterator struct HasNoContiguousIteratorConcept { private: const int *value; public: using iterator_category = std::contiguous_iterator_tag; // no iterator_concept using value_type = int; using pointer = int *; using reference = const int &; using difference_type = int; HasNoContiguousIteratorConcept(const int *value) : value(value) {} HasNoContiguousIteratorConcept(const HasNoContiguousIteratorConcept &other) = default; const int &operator*() const { return *value; } HasNoContiguousIteratorConcept &operator++() { value++; return *this; } HasNoContiguousIteratorConcept operator++(int) { auto tmp = HasNoContiguousIteratorConcept(value); value++; return tmp; } void operator+=(difference_type v) { value += v; } void operator-=(difference_type v) { value -= v; } HasNoContiguousIteratorConcept operator+(difference_type v) const { return HasNoContiguousIteratorConcept(value + v); } HasNoContiguousIteratorConcept operator-(difference_type v) const { return HasNoContiguousIteratorConcept(value - v); } friend HasNoContiguousIteratorConcept operator+(difference_type v, const HasNoContiguousIteratorConcept &it) { return it + v; } int operator-(const HasNoContiguousIteratorConcept &other) const { return value - other.value; } bool operator<(const HasNoContiguousIteratorConcept &other) const { return value < other.value; } bool operator==(const HasNoContiguousIteratorConcept &other) const { return value == other.value; } bool operator!=(const HasNoContiguousIteratorConcept &other) const { return value != other.value; } }; #endif // MARK: Types that are not actually iterators struct HasNoIteratorCategory { int value; const int &operator*() const { return value; } HasNoIteratorCategory &operator++() { value++; return *this; } bool operator==(const HasNoIteratorCategory &other) const { return value == other.value; } }; struct HasInvalidIteratorCategory { struct NotAnIteratorTag {}; int value; using iterator_category = NotAnIteratorTag; const int &operator*() const { return value; } HasInvalidIteratorCategory &operator++() { value++; return *this; } bool operator==(const HasInvalidIteratorCategory &other) const { return value == other.value; } }; struct HasNoEqualEqual { int value; using iterator_category = std::input_iterator_tag; const int &operator*() const { return value; } HasNoEqualEqual &operator++() { value++; return *this; } }; struct HasInvalidEqualEqual { int value; using iterator_category = std::input_iterator_tag; const int &operator*() const { return value; } HasInvalidEqualEqual &operator++() { value++; return *this; } bool operator==(const int &other) const { // wrong type return value == other; } }; struct HasNoIncrementOperator { int value; using iterator_category = std::input_iterator_tag; const int &operator*() const { return value; } bool operator==(const HasNoIncrementOperator &other) const { return value == other.value; } }; struct HasNoPreIncrementOperator { int value; using iterator_category = std::input_iterator_tag; const int &operator*() const { return value; } HasNoPreIncrementOperator operator++(int) { // post-increment HasNoPreIncrementOperator tmp = {value}; value++; return tmp; } bool operator==(const HasNoPreIncrementOperator &other) const { return value == other.value; } }; struct HasNoDereferenceOperator { int value; using iterator_category = std::input_iterator_tag; HasNoDereferenceOperator &operator++() { value++; return *this; } bool operator==(const HasNoDereferenceOperator &other) const { return value == other.value; } }; // MARK: Types that claim to be random access iterators, but actually aren't. struct HasNoMinusOperator { int value; using iterator_category = std::random_access_iterator_tag; using value_type = int; using pointer = int *; using reference = const int &; using difference_type = int; HasNoMinusOperator(int value) : value(value) {} HasNoMinusOperator(const HasNoMinusOperator &other) = default; const int &operator*() const { return value; } HasNoMinusOperator &operator++() { value++; return *this; } void operator+=(difference_type v) { value += v; } void operator-=(difference_type v) { value -= v; } HasNoMinusOperator operator+(difference_type v) const { return HasNoMinusOperator(value + v); } HasNoMinusOperator operator-(difference_type v) const { return HasNoMinusOperator(value - v); } friend HasNoMinusOperator operator+(difference_type v, const HasNoMinusOperator &it) { return it + v; } bool operator<(const HasNoMinusOperator &other) const { return value < other.value; } bool operator==(const HasNoMinusOperator &other) const { return value == other.value; } bool operator!=(const HasNoMinusOperator &other) const { return value != other.value; } }; struct HasNoPlusEqualOperator { int value; using iterator_category = std::random_access_iterator_tag; using value_type = int; using pointer = int *; using reference = const int &; using difference_type = int; HasNoPlusEqualOperator(int value) : value(value) {} HasNoPlusEqualOperator(const HasNoPlusEqualOperator &other) = default; const int &operator*() const { return value; } HasNoPlusEqualOperator &operator++() { value++; return *this; } void operator-=(difference_type v) { value -= v; } HasNoPlusEqualOperator operator+(difference_type v) const { return HasNoPlusEqualOperator(value + v); } HasNoPlusEqualOperator operator-(difference_type v) const { return HasNoPlusEqualOperator(value - v); } friend HasNoPlusEqualOperator operator+(difference_type v, const HasNoPlusEqualOperator &it) { return it + v; } int operator-(const HasNoPlusEqualOperator &other) const { return value - other.value; } bool operator<(const HasNoPlusEqualOperator &other) const { return value < other.value; } bool operator==(const HasNoPlusEqualOperator &other) const { return value == other.value; } bool operator!=(const HasNoPlusEqualOperator &other) const { return value != other.value; } }; // MARK: Templated iterators template struct TemplatedIterator { T value; using iterator_category = std::input_iterator_tag; using value_type = T; using pointer = T *; using reference = const T &; using difference_type = int; TemplatedIterator(int value) : value(value) {} TemplatedIterator(const TemplatedIterator &other) = default; const int &operator*() const { return value; } TemplatedIterator &operator++() { value++; return *this; } TemplatedIterator operator++(int) { auto tmp = TemplatedIterator(value); value++; return tmp; } bool operator==(const TemplatedIterator &other) const { return value == other.value; } }; using TemplatedIteratorInt = TemplatedIterator; template struct TemplatedIteratorOutOfLineEq { T value; using iterator_category = std::input_iterator_tag; using value_type = T; using pointer = T *; using reference = const T &; using difference_type = int; TemplatedIteratorOutOfLineEq(int value) : value(value) {} TemplatedIteratorOutOfLineEq(const TemplatedIteratorOutOfLineEq &other) = default; const int &operator*() const { return value; } TemplatedIteratorOutOfLineEq &operator++() { value++; return *this; } TemplatedIteratorOutOfLineEq operator++(int) { auto tmp = TemplatedIteratorOutOfLineEq(value); value++; return tmp; } }; template bool operator==(const TemplatedIteratorOutOfLineEq &lhs, const TemplatedIteratorOutOfLineEq &rhs) { return lhs.value == rhs.value; } using TemplatedIteratorOutOfLineEqInt = TemplatedIteratorOutOfLineEq; template struct TemplatedRACIteratorOutOfLineEq { T value; using iterator_category = std::random_access_iterator_tag; using value_type = T; using pointer = T *; using reference = const T &; using difference_type = int; TemplatedRACIteratorOutOfLineEq(int value) : value(value) {} TemplatedRACIteratorOutOfLineEq(const TemplatedRACIteratorOutOfLineEq &other) = default; const int &operator*() const { return value; } TemplatedRACIteratorOutOfLineEq &operator++() { value++; return *this; } TemplatedRACIteratorOutOfLineEq &operator--() { value--; return *this; } TemplatedRACIteratorOutOfLineEq operator++(int) { auto tmp = TemplatedRACIteratorOutOfLineEq(value); value++; return tmp; } TemplatedRACIteratorOutOfLineEq &operator+=(difference_type v) { value += v; return *this; } TemplatedRACIteratorOutOfLineEq &operator-=(difference_type v) { value -= v; return *this; } TemplatedRACIteratorOutOfLineEq operator+(difference_type v) const { return TemplatedRACIteratorOutOfLineEq(value + v); } TemplatedRACIteratorOutOfLineEq operator-(difference_type v) const { return TemplatedRACIteratorOutOfLineEq(value - v); } }; template bool operator==(const TemplatedRACIteratorOutOfLineEq &lhs, const TemplatedRACIteratorOutOfLineEq &rhs) { return lhs.value == rhs.value; } template typename TemplatedRACIteratorOutOfLineEq::difference_type operator-(const TemplatedRACIteratorOutOfLineEq &lhs, const TemplatedRACIteratorOutOfLineEq &rhs) { return lhs.value - rhs.value; } using TemplatedRACIteratorOutOfLineEqInt = TemplatedRACIteratorOutOfLineEq; // MARK: Iterator types that use inheritance struct BaseIntIterator { using value_type = int; using reference = const int &; int value; BaseIntIterator(int value) : value(value) {} reference operator*() const { return value; } bool operator==(const BaseIntIterator &other) const { return value == other.value; } bool operator!=(const BaseIntIterator &other) const { return value != other.value; } }; struct InheritedConstIterator : BaseIntIterator { using iterator_category = std::input_iterator_tag; using pointer = int *; using difference_type = int; InheritedConstIterator(int value) : BaseIntIterator(value) {} InheritedConstIterator(const InheritedConstIterator &other) = default; InheritedConstIterator &operator++() { value++; return *this; } InheritedConstIterator operator++(int) { auto tmp = InheritedConstIterator(value); value++; return tmp; } }; // MARK: Templated iterator types that use inheritance template struct BaseTemplatedIterator { using value_type = T; using reference = const T &; T value; BaseTemplatedIterator(T value) : value(value) {} reference operator*() const { return value; } bool operator==(const BaseTemplatedIterator &other) const { return value == other.value; } bool operator!=(const BaseTemplatedIterator &other) const { return value != other.value; } }; template struct InheritedTemplatedConstIterator : BaseTemplatedIterator { using iterator_category = std::input_iterator_tag; using pointer = int *; using difference_type = int; InheritedTemplatedConstIterator(T value) : BaseTemplatedIterator(value) {} InheritedTemplatedConstIterator(const InheritedTemplatedConstIterator &other) = default; InheritedTemplatedConstIterator &operator++() { BaseTemplatedIterator::value++; return *this; } InheritedTemplatedConstIterator operator++(int) { auto tmp = InheritedTemplatedConstIterator(BaseTemplatedIterator::value); BaseTemplatedIterator::value++; return tmp; } }; typedef InheritedTemplatedConstIterator InheritedTemplatedConstIteratorInt; template struct BaseTemplatedRACIterator { using value_type = T; using reference = const T &; using difference_type = int; T value; BaseTemplatedRACIterator(T value) : value(value) {} reference operator*() const { return value; } bool operator==(const BaseTemplatedRACIterator &other) const { return value == other.value; } bool operator!=(const BaseTemplatedRACIterator &other) const { return value != other.value; } }; template struct InheritedTemplatedConstRACIterator : BaseTemplatedRACIterator { using _super = BaseTemplatedRACIterator; using iterator_category = std::random_access_iterator_tag; using pointer = int *; InheritedTemplatedConstRACIterator(T value) : BaseTemplatedRACIterator(value) {} InheritedTemplatedConstRACIterator( const InheritedTemplatedConstRACIterator &other) = default; InheritedTemplatedConstRACIterator &operator++() { _super::value++; return *this; } InheritedTemplatedConstRACIterator operator++(int) { auto tmp = InheritedTemplatedConstRACIterator(_super::value); _super::value++; return tmp; } InheritedTemplatedConstRACIterator operator+(typename _super::difference_type v) const { return {_super::value + v}; } InheritedTemplatedConstRACIterator operator-(typename _super::difference_type v) const { return {_super::value - v}; } friend InheritedTemplatedConstRACIterator operator+(typename _super::difference_type v, const InheritedTemplatedConstRACIterator &it) { return it + v; } int operator-(const InheritedTemplatedConstRACIterator &other) const { return _super::value - other.value; } void operator+=(typename _super::difference_type v) { _super::value += v; } void operator-=(typename _super::difference_type v) { _super::value -= v; } bool operator<(const InheritedTemplatedConstRACIterator &other) const { return _super::value < other.value; } }; typedef InheritedTemplatedConstRACIterator InheritedTemplatedConstRACIteratorInt; struct InheritedTypedConstRACIterator: InheritedTemplatedConstRACIterator { using _super = InheritedTemplatedConstRACIterator; using iterator_category = std::random_access_iterator_tag; using pointer = int *; InheritedTypedConstRACIterator(int x) : InheritedTemplatedConstRACIterator(value) {} int operator-(const InheritedTypedConstRACIterator &other) const { return _super::value - other.value; } void operator+=(typename _super::difference_type v) { _super::value += v; } }; template struct BaseTemplatedRACIteratorOutOfLineOps { using value_type = T; using reference = const T &; using difference_type = int; T value; BaseTemplatedRACIteratorOutOfLineOps(T value) : value(value) {} reference operator*() const { return value; } }; template bool operator==(const BaseTemplatedRACIteratorOutOfLineOps &lhs, const BaseTemplatedRACIteratorOutOfLineOps &rhs) { return lhs.value == rhs.value; } template bool operator!=(const BaseTemplatedRACIteratorOutOfLineOps &lhs, const BaseTemplatedRACIteratorOutOfLineOps &rhs) { return lhs.value != rhs.value; } template bool operator<(const BaseTemplatedRACIteratorOutOfLineOps &lhs, const BaseTemplatedRACIteratorOutOfLineOps &rhs) { return lhs.value < rhs.value; } template typename BaseTemplatedRACIteratorOutOfLineOps::difference_type operator-(const BaseTemplatedRACIteratorOutOfLineOps &lhs, const BaseTemplatedRACIteratorOutOfLineOps &rhs) { return lhs.value - rhs.value; } template BaseTemplatedRACIteratorOutOfLineOps operator+( const BaseTemplatedRACIteratorOutOfLineOps &lhs, typename BaseTemplatedRACIteratorOutOfLineOps::difference_type rhs) { return {lhs.value + rhs}; } template BaseTemplatedRACIteratorOutOfLineOps operator-( const BaseTemplatedRACIteratorOutOfLineOps &lhs, typename BaseTemplatedRACIteratorOutOfLineOps::difference_type rhs) { return {lhs.value - rhs}; } template BaseTemplatedRACIteratorOutOfLineOps operator+(typename BaseTemplatedRACIteratorOutOfLineOps::difference_type lhs, const BaseTemplatedRACIteratorOutOfLineOps &rhs) { return {rhs.value + lhs}; } template struct InheritedTemplatedConstRACIteratorOutOfLineOps : BaseTemplatedRACIteratorOutOfLineOps { using _super = BaseTemplatedRACIteratorOutOfLineOps; using _self = InheritedTemplatedConstRACIteratorOutOfLineOps; using iterator_category = std::random_access_iterator_tag; using pointer = int *; InheritedTemplatedConstRACIteratorOutOfLineOps(T value) : _super(value) {} InheritedTemplatedConstRACIteratorOutOfLineOps(const _self &other) = default; _self &operator++() { _super::value++; return *this; } _self operator++(int) { auto tmp = _self(_super::value); _super::value++; return tmp; } void operator+=(typename _super::difference_type v) { _super::value += v; } void operator-=(typename _super::difference_type v) { _super::value -= v; } }; typedef InheritedTemplatedConstRACIteratorOutOfLineOps InheritedTemplatedConstRACIteratorOutOfLineOpsInt; struct InputOutputIterator { private: int value; public: struct iterator_category : std::input_iterator_tag, std::output_iterator_tag {}; using value_type = int; using pointer = int *; using reference = int &; using const_reference = const int &; using difference_type = int; InputOutputIterator(int value) : value(value) {} InputOutputIterator(const InputOutputIterator &other) = default; const_reference operator*() const { return value; } reference operator*() { return value; } InputOutputIterator &operator++() { value++; return *this; } InputOutputIterator operator++(int) { auto tmp = InputOutputIterator(value); value++; return tmp; } bool operator==(const InputOutputIterator &other) const { return value == other.value; } bool operator!=(const InputOutputIterator &other) const { return value != other.value; } }; struct InputOutputConstIterator { private: int *value; public: struct iterator_category : std::input_iterator_tag, std::output_iterator_tag {}; using value_type = int; using pointer = int *; using reference = int &; using difference_type = int; InputOutputConstIterator(int *value) : value(value) {} InputOutputConstIterator(const InputOutputConstIterator &other) = default; reference operator*() const { return *value; } InputOutputConstIterator &operator++() { value++; return *this; } InputOutputConstIterator operator++(int) { auto tmp = InputOutputConstIterator(value); value++; return tmp; } bool operator==(const InputOutputConstIterator &other) const { return value == other.value; } bool operator!=(const InputOutputConstIterator &other) const { return value != other.value; } }; /// clang::StmtIteratorBase class ProtectedIteratorBase { protected: int value; ProtectedIteratorBase() : value(0) {} }; /// clang::StmtIteratorImpl template class ProtectedIteratorImpl : public ProtectedIteratorBase { protected: ProtectedIteratorImpl(const ProtectedIteratorBase& RHS) : ProtectedIteratorBase(RHS) {} public: using iterator_category = std::forward_iterator_tag; using value_type = int; using difference_type = std::ptrdiff_t; using pointer = int *; using reference = int &; ProtectedIteratorImpl() = default; DERIVED& operator++() { value++; return static_cast(*this); } DERIVED operator++(int) { DERIVED tmp = static_cast(*this); operator++(); return tmp; } friend bool operator==(const DERIVED &LHS, const DERIVED &RHS) { return LHS.value == RHS.value; } reference operator*() const { return value; } }; /// StmtIterator struct HasInheritedProtectedCopyConstructor : public ProtectedIteratorImpl { HasInheritedProtectedCopyConstructor() = default; private: HasInheritedProtectedCopyConstructor(const ProtectedIteratorBase &other) : ProtectedIteratorImpl(other) {} }; #endif // TEST_INTEROP_CXX_STDLIB_INPUTS_CUSTOM_ITERATOR_H