<commit_before>/*******************************************************
 * Copyright (c) 2018, ArrayFire
 * All rights reserved.
 *
 * This file is distributed under 3-clause BSD license.
 * The complete license agreement can be obtained at:
 * http://arrayfire.com/licenses/BSD-3-Clause
 ********************************************************/

#pragma once
#include <Param.hpp>
#include <af/dim4.hpp>

#include <array>
#include <cstddef>
#include <iterator>
#include <vector>

namespace cpu {

/// A Param iterator that iterates through a Param object
template<typename T>
class ParamIterator {
   public:
    using difference_type   = ptrdiff_t;
    using value_type        = T;
    using pointer           = T*;
    using reference         = T&;
    using iterator_category = std::forward_iterator_tag;

    /// Creates a sentinel iterator. This is equivalent to the end iterator
    ParamIterator() noexcept
        : ptr(nullptr)
        , dims(1)
        , stride(1)
        , dim_index{dims[0], dims[1], dims[2], dims[3]} {}

    /// ParamIterator Constructor
    ParamIterator(cpu::Param<T>& in) noexcept
        : ptr(in.get())
        , dims(in.dims())
        , stride(calcIteratorStrides(dims, in.strides()))
        , dim_index{in.dims()[0], in.dims()[1], in.dims()[2], in.dims()[3]} {}

    ParamIterator(cpu::CParam<typename std::remove_const<T>::type>& in) noexcept
        : ptr(const_cast<pointer>(in.get()))
        , dims(in.dims())
        , stride(calcIteratorStrides(dims, in.strides()))
        , dim_index{in.dims()[0], in.dims()[1], in.dims()[2], in.dims()[3]} {}

    /// The equality operator
    bool operator==(const ParamIterator& other) const noexcept {
        return ptr == other.ptr;
    }

    /// The inequality operator
    bool operator!=(const ParamIterator& other) const noexcept {
        return ptr != other.ptr;
    }

    /// Advances the iterator, pre increment operator
    ParamIterator& operator++() noexcept {
        for (int i = 0; i < AF_MAX_DIMS; i++) {
            dim_index[i]--;
            ptr += stride[i];
            if (dim_index[i]) { return *this; }
            dim_index[i] = dims[i];
        }
        ptr = nullptr;
        return *this;
    }

    /// Advances the iterator by count elements
    ParamIterator& operator+=(std::size_t count) noexcept {
        while (count-- > 0) { operator++(); }
        return *this;
    }

    const reference operator*() const noexcept { return *ptr; }

    const pointer operator->() const noexcept { return ptr; }

    ParamIterator(const ParamIterator<T>& other) = default;
    ParamIterator(ParamIterator<T>&& other)      = default;
    ~ParamIterator() noexcept                    = default;
    ParamIterator<T>& operator=(const ParamIterator<T>& other) noexcept =
        default;
    ParamIterator<T>& operator=(ParamIterator<T>&& other) noexcept = default;

   private:
    T* ptr;<commit_msg>Fix constness of operator* in ParamIterator<commit_after>/*******************************************************
 * Copyright (c) 2018, ArrayFire
 * All rights reserved.
 *
 * This file is distributed under 3-clause BSD license.
 * The complete license agreement can be obtained at:
 * http://arrayfire.com/licenses/BSD-3-Clause
 ********************************************************/

#pragma once
#include <Param.hpp>
#include <af/dim4.hpp>

#include <array>
#include <cstddef>
#include <iterator>
#include <vector>

namespace cpu {

/// A Param iterator that iterates through a Param object
template<typename T>
class ParamIterator {
   public:
    using difference_type   = ptrdiff_t;
    using value_type        = T;
    using pointer           = T*;
    using reference         = T&;
    using const_reference   = const T&;
    using iterator_category = std::forward_iterator_tag;

    /// Creates a sentinel iterator. This is equivalent to the end iterator
    ParamIterator() noexcept
        : ptr(nullptr)
        , dims(1)
        , stride(1)
        , dim_index{dims[0], dims[1], dims[2], dims[3]} {}

    /// ParamIterator Constructor
    ParamIterator(cpu::Param<T>& in) noexcept
        : ptr(in.get())
        , dims(in.dims())
        , stride(calcIteratorStrides(dims, in.strides()))
        , dim_index{in.dims()[0], in.dims()[1], in.dims()[2], in.dims()[3]} {}

    ParamIterator(cpu::CParam<typename std::remove_const<T>::type>& in) noexcept
        : ptr(const_cast<pointer>(in.get()))
        , dims(in.dims())
        , stride(calcIteratorStrides(dims, in.strides()))
        , dim_index{in.dims()[0], in.dims()[1], in.dims()[2], in.dims()[3]} {}

    /// The equality operator
    bool operator==(const ParamIterator& other) const noexcept {
        return ptr == other.ptr;
    }

    /// The inequality operator
    bool operator!=(const ParamIterator& other) const noexcept {
        return ptr != other.ptr;
    }

    /// Advances the iterator, pre increment operator
    ParamIterator& operator++() noexcept {
        for (int i = 0; i < AF_MAX_DIMS; i++) {
            dim_index[i]--;
            ptr += stride[i];
            if (dim_index[i]) { return *this; }
            dim_index[i] = dims[i];
        }
        ptr = nullptr;
        return *this;
    }

    /// Advances the iterator by count elements
    ParamIterator& operator+=(std::size_t count) noexcept {
        while (count-- > 0) { operator++(); }
        return *this;
    }

    reference operator*() noexcept { return *ptr; }

    const_reference operator*() const noexcept { return *ptr; }

    const pointer operator->() const noexcept { return ptr; }

    ParamIterator(const ParamIterator<T>& other) = default;
    ParamIterator(ParamIterator<T>&& other)      = default;
    ~ParamIterator() noexcept                    = default;
    ParamIterator<T>& operator=(const ParamIterator<T>& other) noexcept =
        default;
    ParamIterator<T>& operator=(ParamIterator<T>&& other) noexcept = default;

   private:
    T* ptr;
{'fraction_non_alphanumeric': 0.17005887300252312, 'fraction_numerical': 0.007737594617325484, 'mean_word_length': 2.8361290322580643, 'pattern_counts': {'":': 0, '<': 39, '<?xml version=': 0, '>': 41, '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': '6181132', 'n_tokens_mistral': 1755, 'n_tokens_neox': 1753, 'n_words': 456}