<commit_before>#pragma once

#include <cstddef>  // ptrdiff_t
#include <iterator>  // iterator, forward_iterator_tag
#include <memory>  // addressof
#include <type_traits>  // remove_cv_t

template<
    class QualifiedType,
    class UnqualifiedType = std::remove_cv_t<QualifiedType>,
    class IteratorBase = std::iterator<
        std::forward_iterator_tag,
        UnqualifiedType,
        std::ptrdiff_t,
        QualifiedType*,
        QualifiedType&
    >
> struct ForwardVectorIterator;

// This is just a simple container class for illustrative purposes.
//
template<class T>
class ForwardVector {
    T data[10];

  public:
    using iterator = ForwardVectorIterator<T>;
    using const_iterator = ForwardVectorIterator<const T>;

    iterator begin() { return iterator(data); }
    const_iterator begin() const { return cbegin(); }
    const_iterator cbegin() const { return const_iterator(data); }
    iterator end() { return iterator(data+10); }
    const_iterator end() const { return cbegin(); }
    const_iterator cend() const { return const_iterator(data+10); }
};

// Inheriting from std::iterator ensures that there exists an appropriate
// specialization of the std::iterator_traits class template.
//
// Notice that `ForwardVectorIterator<const T>::value_type` is `T`,
// not `const T`. This follows the precedent set by the standard library
// containers.
//
// [iterator.requirements.general]p4: In the language of the standard,
// `ForwardVectorIterator<T>` is a forward iterator, an input iterator, an
// output iterator, and a mutable iterator.
// `ForwardVectorIterator<const T>` is a forward iterator, an input iterator,
// and a constant iterator.
//
template<class QualifiedType,
         class UnqualifiedType /* = std::remove_cv_t<QualifiedType> */,
         class IteratorBase /* = std::iterator<...> */ >
struct ForwardVectorIterator : IteratorBase
{
    using typename IteratorBase::reference;
    using typename IteratorBase::pointer;

    // [forward.iterators]p1.2: MyForwardIterator must be DefaultConstructible,
    // which implies that a default-constructed MyForwardIterator must be able to be
    // the source of a move or copy operation. (Don't leave any data members of
    // primitive types uninitialized!)
    //
    // [forward.iterators]p2: Comparing `MyForwardIterator{} == MyForwardIterator{}`
    // must deterministically return `true`. It is often useful to have
    // `MyForwardIterator{} == MyContainer{}.end()`, but it's not required.
    //
    // Using `{}` instead of `=default` makes the constructor user-provided, which
    // means the user is allowed to construct `const Vector<int>::iterator foo;`
    // with no initializer.
    //
    ForwardVectorIterator() {}

    // You'll usually need some way to construct an iterator from the innards
    // of a container. Remember to make this constructor `private` and `explicit`
    // so that it will interfere as little as possible with the user's own code.
    // Implicit conversions from `nullptr` are particularly insidious.
    //
    friend class ForwardVector<UnqualifiedType>;
  private:
    explicit ForwardVectorIterator(QualifiedType* ptr) {
        // perform your custom initialization
    }
  public:

    // Explicitly defaulting these special member functions prevents you from
    // accidentally disabling any of them via (for example) adding a user-provided
    // destructor.
    //
#if ITERATOR_IS_MOVEONLY
    ForwardVectorIterator(ForwardVectorIterator const&) = delete;
    ForwardVectorIterator& operator=(ForwardVectorIterator const&) = delete;
#else
    ForwardVectorIterator(ForwardVectorIterator const&) = default;
    ForwardVectorIterator& operator=(ForwardVectorIterator const&) = default;
#endif
    ~ForwardVectorIterator() = default;<commit_msg>Explain about move-only "iterators".<commit_after>#pragma once

#include <cstddef>  // ptrdiff_t
#include <iterator>  // iterator, forward_iterator_tag
#include <memory>  // addressof
#include <type_traits>  // remove_cv_t

template<
    class QualifiedType,
    class UnqualifiedType = std::remove_cv_t<QualifiedType>,
    class IteratorBase = std::iterator<
        std::forward_iterator_tag,
        UnqualifiedType,
        std::ptrdiff_t,
        QualifiedType*,
        QualifiedType&
    >
> struct ForwardVectorIterator;

// This is just a simple container class for illustrative purposes.
//
template<class T>
class ForwardVector {
    T data[10];

  public:
    using iterator = ForwardVectorIterator<T>;
    using const_iterator = ForwardVectorIterator<const T>;

    iterator begin() { return iterator(data); }
    const_iterator begin() const { return cbegin(); }
    const_iterator cbegin() const { return const_iterator(data); }
    iterator end() { return iterator(data+10); }
    const_iterator end() const { return cbegin(); }
    const_iterator cend() const { return const_iterator(data+10); }
};

// Inheriting from std::iterator ensures that there exists an appropriate
// specialization of the std::iterator_traits class template.
//
// Notice that `ForwardVectorIterator<const T>::value_type` is `T`,
// not `const T`. This follows the precedent set by the standard library
// containers.
//
// [iterator.requirements.general]p4: In the language of the standard,
// `ForwardVectorIterator<T>` is a forward iterator, an input iterator, an
// output iterator, and a mutable iterator.
// `ForwardVectorIterator<const T>` is a forward iterator, an input iterator,
// and a constant iterator.
//
template<class QualifiedType,
         class UnqualifiedType /* = std::remove_cv_t<QualifiedType> */,
         class IteratorBase /* = std::iterator<...> */ >
struct ForwardVectorIterator : IteratorBase
{
    using typename IteratorBase::reference;
    using typename IteratorBase::pointer;

    // [forward.iterators]p1.2: MyForwardIterator must be DefaultConstructible,
    // which implies that a default-constructed MyForwardIterator must be able to be
    // the source of a move or copy operation. (Don't leave any data members of
    // primitive types uninitialized!)
    //
    // [forward.iterators]p2: Comparing `MyForwardIterator{} == MyForwardIterator{}`
    // must deterministically return `true`. It is often useful to have
    // `MyForwardIterator{} == MyContainer{}.end()`, but it's not required.
    //
    // Using `{}` instead of `=default` makes the constructor user-provided, which
    // means the user is allowed to construct `const Vector<int>::iterator foo;`
    // with no initializer.
    //
    ForwardVectorIterator() {}

    // You'll usually need some way to construct an iterator from the innards
    // of a container. Remember to make this constructor `private` and `explicit`
    // so that it will interfere as little as possible with the user's own code.
    // Implicit conversions from `nullptr` are particularly insidious.
    //
    friend class ForwardVector<UnqualifiedType>;
  private:
    explicit ForwardVectorIterator(QualifiedType* ptr) {
        // perform your custom initialization
    }
  public:

    // Explicitly defaulting these special member functions prevents you from
    // accidentally disabling any of them via (for example) adding a user-provided
    // destructor.
    //
#if ITERATOR_IS_MOVEONLY
    // [iterator.iterators]p2.1: According to the standard, iterators must be
    // copyable; a move-only type does not conform to the "Iterator" concept.
    // However, in practice it's reasonable to imagine an iterator (such as a
    // database cursor) that cannot be meaningfully copied. For such
    // iterators, it suffices to delete the special member functions and the
    // postfix operator++.
    //
    ForwardVectorIterator(ForwardVectorIterator const&) = delete;
    ForwardVectorIterator& operator=(ForwardVectorIterator const&) = delete;
#else
    ForwardVectorIterator(ForwardVectorIterator const&) = default;
    ForwardVectorIterator& operator=(ForwardVectorIterator const&) = default;
#endif
    ~ForwardVectorIterator() = default;
{'fraction_non_alphanumeric': 0.09914061526964753, 'fraction_numerical': 0.0027400672561962883, 'mean_word_length': 3.6523754345307067, 'pattern_counts': {'":': 0, '<': 39, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7615064', 'n_tokens_mistral': 2176, 'n_tokens_neox': 2090, 'n_words': 740}