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
}
输出