<commit_before>#pragma once

#include <set>

// TODO use move semantics

namespace simple_graph {

template<typename T>
class Vertex {
public:
    Vertex() : idx_(0), data_() {
        ++default_creations;
    }
    Vertex(const Vertex<T> &v) {
        ++copies;
        idx_ = v.idx_;
        data_ = v.data_;
    }
    Vertex(Vertex<T> &&v) noexcept(noexcept(
                std::is_nothrow_move_constructible<T>::value
                    && std::is_nothrow_move_assignable<T>::value)) {
        ++moves;
        idx_ = v.idx_;
        std::swap(data_, v.data_);
    }
    explicit Vertex(size_t idx) : idx_(idx), data_() {
        ++creations;
    }
    Vertex(size_t idx, const T &data) : idx_(idx), data_(data) {
        ++creations;
    }
    virtual ~Vertex() = default;

    size_t idx() const { return idx_; }
    T data() const { return data_; }

    bool operator<(const Vertex<T> &vertex) const {
        return idx_ < vertex.idx_;
    }

    Vertex &operator=(const Vertex<T> &v) {
        ++assigns;
        if (this != &v) {
            idx_ = v.idx_;
            data_ = v.data_;
        }
        return *this;
    }

    Vertex &operator=(Vertex<T> &&v) noexcept(noexcept(
                std::is_nothrow_move_constructible<T>::value
                    && std::is_nothrow_move_assignable<T>::value)) {
        ++moves;
        if (this != &v) {
            idx_ = v.idx_;
            std::swap(data_, v.data_);
        }
        return *this;
    }

public:
    static int default_creations;
    static int creations;
    static int copies;
    static int moves;
    static int assigns;

    static std::string stat() {
        return "creations: " + std::to_string(default_creations) + " + " + std::to_string(creations)
                + "; copies: " + std::to_string(copies)
                + "; moves: " + std::to_string(moves)
                + "; assigns: " + std::to_string(assigns);
    }

private:
    size_t idx_;
    T data_;
};

template<typename T> int Vertex<T>::default_creations = 0;
template<typename T> int Vertex<T>::creations = 0;
template<typename T> int Vertex<T>::copies = 0;
template<typename T> int Vertex<T>::moves = 0;
template<typename T> int Vertex<T>::assigns = 0;

template<typename T>
class Edge {
    static_assert(std::is_integral<T>::value || std::is_floating_point<T>::value,
            "Integer of floating point required.");

public:
    Edge() : idx1_(0), idx2_(0), weight_() {
        ++default_creations;
    }
    Edge(const Edge<T> &edge) : idx1_(edge.idx1_), idx2_(edge.idx2_), weight_(edge.weight_) {
        ++copies;
    }
    Edge(Edge<T> &&edge) noexcept(noexcept(
                std::is_nothrow_move_constructible<T>::value
                    && std::is_nothrow_move_assignable<T>::value)) : idx1_(edge.idx1_), idx2_(edge.idx2_) {
        ++moves;
        std::swap(weight_, edge.weight_);
    }

    Edge(size_t idx1, size_t idx2) : idx1_(idx1), idx2_(idx2), weight_(1) {
        ++creations;
    }
    Edge(size_t idx1, size_t idx2, const T &weight) : idx1_(idx1), idx2_(idx2), weight_(weight) {
        ++creations;
    }

    Edge &operator=(const Edge<T> &edge) {
        ++assigns;
        if (this != &edge) {
            idx1_ = edge.idx1_;
            idx2_ = edge.idx2_;
            weight_ = edge.weight_;
        }
        return *this;
    }

    Edge &operator=(Edge<T> &&edge) noexcept(noexcept(
                std::is_nothrow_move_constructible<T>::value
                    && std::is_nothrow_move_assignable<T>::value)) {
        ++moves;
        if (this != &edge) {
            idx1_ = edge.idx1_;
            idx2_ = edge.idx2_;
            std::swap(weight_, edge.weight_);
        }
        return *this;
    }

    virtual ~Edge() = default;
    size_t idx1() const { return idx1_; }
    size_t idx2() const { return idx2_; }
    const T &weight() const { return weight_; }

private:
    size_t idx1_;
    size_t idx2_;
    T weight_;
};


template<typename T>
class IteratorImplBase {
public:
    virtual ~IteratorImplBase() = default;
    virtual bool operator==(const IteratorImplBase<T> &it) const = 0;
    virtual bool operator!=(const IteratorImplBase<T> &it) const = 0;
    virtual IteratorImplBase<T> &operator++() = 0;
    virtual T &operator*() = 0;
};

template<typename T>
class iterator {
public:
    iterator(IteratorImplBase<T> *b) : base_impl(b) {}

    bool operator==(const iterator<T> &it) const {
        return base_impl->operator==(*it.base_impl);
    }

    bool operator!=(const iterator<T> &it) const {
        return !operator==(it);
    }<commit_msg>Add creations stat in Edge class<commit_after>#pragma once

#include <set>

// TODO use move semantics

namespace simple_graph {

template<typename T>
class Vertex {
public:
    Vertex() : idx_(0), data_() {
        ++default_creations;
    }
    Vertex(const Vertex<T> &v) {
        ++copies;
        idx_ = v.idx_;
        data_ = v.data_;
    }
    Vertex(Vertex<T> &&v) noexcept(noexcept(
                std::is_nothrow_move_constructible<T>::value
                    && std::is_nothrow_move_assignable<T>::value)) {
        ++moves;
        idx_ = v.idx_;
        std::swap(data_, v.data_);
    }
    explicit Vertex(size_t idx) : idx_(idx), data_() {
        ++creations;
    }
    Vertex(size_t idx, const T &data) : idx_(idx), data_(data) {
        ++creations;
    }
    virtual ~Vertex() = default;

    size_t idx() const { return idx_; }
    T data() const { return data_; }

    bool operator<(const Vertex<T> &vertex) const {
        return idx_ < vertex.idx_;
    }

    Vertex &operator=(const Vertex<T> &v) {
        ++assigns;
        if (this != &v) {
            idx_ = v.idx_;
            data_ = v.data_;
        }
        return *this;
    }

    Vertex &operator=(Vertex<T> &&v) noexcept(noexcept(
                std::is_nothrow_move_constructible<T>::value
                    && std::is_nothrow_move_assignable<T>::value)) {
        ++moves;
        if (this != &v) {
            idx_ = v.idx_;
            std::swap(data_, v.data_);
        }
        return *this;
    }

public:
    static int default_creations;
    static int creations;
    static int copies;
    static int moves;
    static int assigns;

    static std::string stat() {
        return "creations: " + std::to_string(default_creations) + " + " + std::to_string(creations)
                + "; copies: " + std::to_string(copies)
                + "; moves: " + std::to_string(moves)
                + "; assigns: " + std::to_string(assigns);
    }

private:
    size_t idx_;
    T data_;
};

template<typename T> int Vertex<T>::default_creations = 0;
template<typename T> int Vertex<T>::creations = 0;
template<typename T> int Vertex<T>::copies = 0;
template<typename T> int Vertex<T>::moves = 0;
template<typename T> int Vertex<T>::assigns = 0;

template<typename T>
class Edge {
    static_assert(std::is_integral<T>::value || std::is_floating_point<T>::value,
            "Integer of floating point required.");

public:
    Edge() : idx1_(0), idx2_(0), weight_() {
        ++default_creations;
    }
    Edge(const Edge<T> &edge) : idx1_(edge.idx1_), idx2_(edge.idx2_), weight_(edge.weight_) {
        ++copies;
    }
    Edge(Edge<T> &&edge) noexcept(noexcept(
                std::is_nothrow_move_constructible<T>::value
                    && std::is_nothrow_move_assignable<T>::value)) : idx1_(edge.idx1_), idx2_(edge.idx2_) {
        ++moves;
        std::swap(weight_, edge.weight_);
    }

    Edge(size_t idx1, size_t idx2) : idx1_(idx1), idx2_(idx2), weight_(1) {
        ++creations;
    }
    Edge(size_t idx1, size_t idx2, const T &weight) : idx1_(idx1), idx2_(idx2), weight_(weight) {
        ++creations;
    }

    Edge &operator=(const Edge<T> &edge) {
        ++assigns;
        if (this != &edge) {
            idx1_ = edge.idx1_;
            idx2_ = edge.idx2_;
            weight_ = edge.weight_;
        }
        return *this;
    }

    Edge &operator=(Edge<T> &&edge) noexcept(noexcept(
                std::is_nothrow_move_constructible<T>::value
                    && std::is_nothrow_move_assignable<T>::value)) {
        ++moves;
        if (this != &edge) {
            idx1_ = edge.idx1_;
            idx2_ = edge.idx2_;
            std::swap(weight_, edge.weight_);
        }
        return *this;
    }

    virtual ~Edge() = default;
    size_t idx1() const { return idx1_; }
    size_t idx2() const { return idx2_; }
    const T &weight() const { return weight_; }

public:
    static int default_creations;
    static int creations;
    static int copies;
    static int moves;
    static int assigns;

    static std::string stat() {
        return "creations: " + std::to_string(default_creations) + " + " + std::to_string(creations)
                + "; copies: " + std::to_string(copies)
                + "; moves: " + std::to_string(moves)
                + "; assigns: " + std::to_string(assigns);
    }
private:
    size_t idx1_;
    size_t idx2_;
    T weight_;
};

template<typename T> int Edge<T>::default_creations = 0;
template<typename T> int Edge<T>::creations = 0;
template<typename T> int Edge<T>::copies = 0;
template<typename T> int Edge<T>::moves = 0;
template<typename T> int Edge<T>::assigns = 0;

template<typename T>
class IteratorImplBase {
public:
    virtual ~IteratorImplBase() = default;
    virtual bool operator==(const IteratorImplBase<T> &it) const = 0;
    virtual bool operator!=(const IteratorImplBase<T> &it) const = 0;
    virtual IteratorImplBase<T> &operator++() = 0;
    virtual T &operator*() = 0;
};

template<typename T>
class iterator {
public:
    iterator(IteratorImplBase<T> *b) : base_impl(b) {}

    bool operator==(const iterator<T> &it) const {
        return base_impl->operator==(*it.base_impl);
    }

    bool operator!=(const iterator<T> &it) const {
        return !operator==(it);
    }
{'fraction_non_alphanumeric': 0.14443655543158535, 'fraction_numerical': 0.010447307029110458, 'mean_word_length': 2.448758307100385, 'pattern_counts': {'":': 0, '<': 97, '<?xml version=': 0, '>': 95, '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': '1331038', 'n_tokens_mistral': 3366, 'n_tokens_neox': 3264, 'n_words': 711}