c++ 17 range的实现

pyhton 的 range 功能非常好用,那么 c++ 怎么来一个呢
下面自己实现一个
目前进度
整数 range
vector range
map range
set 之流不需要 range

直接看测试用例就行, 代码繁琐, 但是有效就行

第二版较第一版更加简洁

第二版

#include <array>
#include <iostream>
#include <map>
#include <utility>
#include <vector>

using namespace std;

class RangeIte {
   public:
    int val;
    int step;

    RangeIte(int val, int step = 1) : val(val), step(step) {}

    RangeIte& operator++() {
        val += step;
        return *this;
    }

    bool operator!=(const RangeIte& rhs) { return this->val < rhs.val; }

    int operator*() { return val; }
};

class Range {
   public:
    int _begin;
    int _end;
    int _step;

    Range(int _begin, int _end, int _step) : _begin(_begin), _end(_end), _step(_step) {}

    Range(int _end) : Range(0, _end, 1) {}

    Range(int _begin, int _end) : Range(_begin, _end, 1) {}

    RangeIte begin() const { return RangeIte(_begin, _step); }

    RangeIte end() const { return RangeIte(_end, _step); }
};

template <template <typename...> typename Container, typename... T>
class ContainerRangeIte {
   public:
    int index;
    typename Container<T...>::const_iterator ite;

    ContainerRangeIte(int index, typename Container<T...>::const_iterator ite) : index(index), ite(ite) {}

    ContainerRangeIte& operator++() {
        index++;
        ++ite;
        return *this;
    }

    bool operator!=(const ContainerRangeIte& rhs) const { return index < rhs.index && ite != rhs.ite; }

    pair<int, typename Container<T...>::const_iterator> operator*() { return pair<int, typename Container<T...>::const_iterator>{index, ite}; }
};

template <template <typename...> typename Container, typename... T>
class ContainerRange {
   public:
    const Container<T...>& _data;

    ContainerRange(const Container<T...>& _data) : _data(_data) {}

    ContainerRangeIte<Container, T...> begin() const { return ContainerRangeIte<Container, T...>{0, _data.begin()}; }

    ContainerRangeIte<Container, T...> end() const { return ContainerRangeIte<Container, T...>{(int)_data.size(), _data.end()}; }
};

auto range(int end) {
    return Range(0, end, 1);
}

auto range(int start, int end) {
    return Range(start, end, 1);
}

auto range(int start, int end, int step) {
    return Range(start, end, step);
}

template <template <typename...> typename Container, typename... T>
auto range(const Container<T...>& data) {
    return ContainerRange<Container, T...>(data);
}

int main() {
    // 一般区间range
    for (auto v : range(3, 11, 2)) {
        cout << v << "\t";
    }
    cout << endl;

    // vector range
    vector<int> data{0, 1, 2, 3, 4, 5, 6};
    for (auto [index, val] : range(data)) {
        cout << "index:" << index << "\tvalue:" << *val << endl;
    }
    cout << endl;

    //  map range
    map<int, string> mis;
    mis[0] = "hello";
    mis[1] = "thank you";
    for (auto [index, val] : range(mis)) {
        cout << index << "\t" << val->first << "\t" << val->second << endl;
    }
    cout << endl;
}

第一版

#include <iostream>
#include <utility>
#include <string>
#include <cstring>
#include <vector>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <unordered_map>
#include <unordered_set>
#include <algorithm>
#include <numeric>

using namespace std;

template<typename ...T>
struct Range;


struct intIterator {
    typedef long VALUE_TYPE;
    explicit intIterator(VALUE_TYPE value) {
        _value = value;
    }

    bool operator != (intIterator& rhs) {
        return getValue() != rhs.getValue();
    }

    VALUE_TYPE operator*() const {
        return getValue();
    }

    const intIterator&  operator ++() {
        ++_value;
        return *this;
    }
private:
    [[nodiscard]] VALUE_TYPE getValue() const{
        return _value;
    }
    VALUE_TYPE _value;


};

template<>
struct Range<int> {
    int left,right;

    Range(int left, int right) {
        this->left = left;
        this->right = right;
    }

    explicit Range(int right) {
        left = 0;
        this->right = right;
    }

    [[nodiscard]] intIterator begin() const {
        return intIterator(left);
    }

    [[nodiscard]] intIterator end() const {
        return intIterator(right);
    }
};

template<typename T>
struct vecIterator {
    explicit vecIterator(const vector<T>& values):_index(0), _values(values){}

    vecIterator(int index, const vector<T>& values):_index(index), _values(values){}

    bool operator!=(const vecIterator& rhs) {
        return getIndex() != rhs.getIndex();
    }

    pair<int, T> operator* () const{
        int index = getIndex();
        return {index, ref(_values[index])};
    }

    const vecIterator& operator++() {
        ++_index;
        return *this;
    }

private:
    [[nodiscard]] int getIndex() const{
        return _index;
    }

    int _index;
    const vector<T>& _values;
};

template<typename T>
struct Range<vecIterator<T>> {
    //typedef long T;
    const vector<T>& values;

    explicit Range(const vector<T>& values):values(values) {}

    [[nodiscard]] vecIterator<T> begin() const {
        return vecIterator<T>(0, values);
    }

    [[nodiscard]] vecIterator<T> end() const {
        return vecIterator<T>(values.size(), values);
    }
};


template<typename KType, typename VType, typename Container = unordered_map<KType, VType>>
struct mapIterator{
    explicit mapIterator(const Container& container1):container(container1), it(container.begin()) {}

    mapIterator(typename Container::const_iterator pos, const Container& container1): container(container1), it(pos){}

    bool operator!=(const mapIterator& rhs) {
        return getIndex() != rhs.getIndex();
    }

    pair<KType, VType> operator* () const{
        auto pos = getIndex();
        return {pos->first, pos->second};
    }

    const mapIterator& operator++() {
        it++;
        return *this;
    }

private:
    [[nodiscard]] typename Container::const_iterator getIndex() const{
        return it;
    }

    const Container& container;
    typename Container::const_iterator it;
};


template<typename KType, typename VType>
struct Range<mapIterator<KType, VType>> {
    const unordered_map<KType, VType>& hash_map;

    explicit Range(const unordered_map<KType, VType>& values):hash_map(values) {}

    [[nodiscard]] mapIterator<KType, VType> begin() const {
        return mapIterator<KType, VType>(hash_map);
    }

    [[nodiscard]] mapIterator<KType, VType> end() const {
        return mapIterator<KType, VType>(hash_map.end(), hash_map);
    }
};


Range<int> range(int left, int right) {
    return Range<int>(left, right);
}

Range<int> range(int right) {
    return Range<int>(0, right);
}

template<typename T>
Range<vecIterator<T>> range(const vector<T>& data) {
    return Range<vecIterator<T>>(data);
}

template<typename KType, typename VType>
Range<mapIterator<KType, VType>> range(const unordered_map<KType, VType>& data) {
    return Range<mapIterator<KType, VType>>(data);
}


int main() {
    vector<int> data;
    // 整数
    for (auto i : range(10)) {
        data.emplace_back(i);
    }

    for (auto i : range(11, 20)) {
        data.emplace_back(i);
    }

    // vector
    for (auto [index, value] : range(data)) {
        cout << index << "\t" << value << endl;
    }

    // map 测试用例
    unordered_map<int, int> om;
    om[1] = 1;
    om[2] = 2;
    om[3] = 3;
    for (auto [k, v] : range(om)) {
        cout << "key: " << k << " value: " << v << endl;
    }
    
    // set 不需要 range
}

输出
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值