[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;    reverse_iterator rbegin()    {        current_value = tail;        return reverse_iterator(this);    }    reverse_iterator rend()    {         return reverse_iterator(nullptr);     }public:    bool includes(int_type num)    {        return head <= num && num <= tail;    }public:    Range() = delete;    virtual ~Range() = default;    Range(int_type _lhs, int_type _rhs) : head(_lhs), tail(_rhs) {}    Range(int_type _rhs) : head(1), tail(_rhs) {}};Colored by Color Scripter | cs |



선언.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;public: //반복자    iterator begin();    iterator end();public: //역순 반복자    reverse_iterator rbegin();    reverse_iterator rend();public:    bool includes(int_type num) const; //포함확인public:    Range() = delete;    virtual ~Range() = default;    Range(int_type _lhs, int_type _rhs);    Range(int_type _rhs);};  Colored by Color Scripter | cs |



구현.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 |