[C++] 범위 표현 클래스 : Range
범위기반 for문에 사용하면 아주 좋다.
이렇게 쓸 수도 있다.
선언+구현 통짜코드
| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091 | class Range{public: using int_type = int;private: int_type head; int_type tail; int_type current_value = 0;public: template <bool is_reverse_ver = false> class iterator_base { public: using pointer = Range * ; private: pointer obj = nullptr; public: iterator_base(pointer p) : obj(p) {} //begin/rbegin 생성 public: iterator_base() = delete; virtual ~iterator_base() = default; iterator_base(const iterator_base&) = default; iterator_base(iterator_base&&) = default; iterator_base& operator=(const iterator_base& rhs) = default; iterator_base& operator=(iterator_base&& rhs) = default; public: iterator_base& operator++() //증가 { if (obj == nullptr) return *this; if constexpr(is_reverse_ver==false) { if (obj->current_value != obj->tail) (obj->current_value)++; else obj = nullptr; } else //reverse_iterator { if (obj->current_value != obj->head) (obj->current_value)--; else obj = nullptr; } return this; } iterator_base operator++(int) { return this->operator++(); } //위임 int operator() const { return obj->current_value; } bool operator==(const iterator_base& rhs) { return this->obj == rhs.obj; } bool operator!=(const iterator_base& rhs) { return this->obj != rhs.obj; } };public: //반복자 using iterator = iterator_base<>; iterator begin() { current_value = head; return iterator(this); } iterator end() { return iterator(nullptr); }public: //역순 반복자 using reverse_iterator = iterator_base
선언.h
| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455 | #pragma once class Range{public: using int_type = int;private: int_type head; int_type tail; int_type current_value = 0;public: template <bool is_reverse_ver = false> class iterator_base { public: using pointer = Range * ; private: pointer obj = nullptr; public: iterator_base(pointer p); //begin/rbegin 생성 public: //기본 생성자/대입 iterator_base() = delete; virtual ~iterator_base() = default; iterator_base(const iterator_base&) = default; iterator_base(iterator_base&&) = default; iterator_base& operator=(const iterator_base& rhs) = default; iterator_base& operator=(iterator_base&& rhs) = default; public: iterator_base & operator++(); //증가 iterator_base operator++(int); //증가 int operator*() const; //참조 bool operator==(const iterator_base& rhs); //비교 bool operator!=(const iterator_base& rhs); //비교 }; public: using iterator = iterator_base<>; using reverse_iterator = iterator_base
구현.cpp
| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192 | //#include "stdafx.h" //visual studio 전용#include "Range.h" template<bool is_reverse_ver>inline Range::iterator_base<is_reverse_ver>::iterator_base(pointer p) : obj(p){} template<bool is_reverse_ver>inline Range::iterator_base<is_reverse_ver>&Range::iterator_base<is_reverse_ver>::operator++(){ if (obj == nullptr) return *this; if constexpr(is_reverse_ver == false) { if (obj->current_value != obj->tail) (obj->current_value)++; else obj = nullptr; } else //reverse_iterator { if (obj->current_value != obj->head) (obj->current_value)--; else obj = nullptr; } return this;} template<bool is_reverse_ver>inline Range::iterator_base<is_reverse_ver>Range::iterator_base<is_reverse_ver>::operator++(int){ return this->operator++();} template<bool is_reverse_ver>inline Range::int_typeRange::iterator_base<is_reverse_ver>::operator() const{ return obj->current_value;} template<bool is_reverse_ver>inline boolRange::iterator_base<is_reverse_ver>::operator==(const Range::iterator_base<is_reverse_ver> & rhs){ return this->obj == rhs.obj;} template<bool is_reverse_ver>inline boolRange::iterator_base<is_reverse_ver>::operator!=(const Range::iterator_base<is_reverse_ver> & rhs){ return this->obj != rhs.obj;} Range::iterator Range::begin(){ current_value = head; return iterator(this);} Range::iterator Range::end(){ return iterator(nullptr);} Range::reverse_iterator Range::rbegin(){ current_value = tail; return reverse_iterator(this);} Range::reverse_iterator Range::rend(){ return reverse_iterator(nullptr);} bool Range::includes(int_type num) const{ return head <= num && num <= tail;} Range::Range(int_type _lhs, int_type _rhs) : head(_lhs), tail(_rhs){} Range::Range(int_type _rhs) : head(1), tail(_rhs){} Colored by Color Scripter | cs |