Search code examples
c++functioncurly-braces

How to make custom keyword statement


How would I go about making a function that uses braces like if/for/while statements? I'm referring to this as a 'keyword statement' because I don't know what else to call it.

Meaning, for example, if I wanted to make a 'repeat' function:

repeat(3)
{
    //do something
}

I guess a better question is, is this possible? If so, how would one go about doing this?


Solution

  • You might define a range similar to a python range:

    // Range
    // =====
    
    #include <iterator>
    #include <utility>
    
    template<typename T>
    class Range
    {
        public:
        typedef T value_type;
    
        public:
        class iterator
        {
            public:
            typedef typename std::forward_iterator_tag iterator_category;
            typedef typename std::size_t size_type;
            typedef typename std::ptrdiff_t difference_type;
            typedef T value_type;
            typedef const T& reference;
            typedef const T* pointer;
    
            public:
            iterator(const T& value) noexcept
            :   m_value(value)
            {}
    
            reference operator * () const noexcept { return m_value; }
            pointer operator -> () const noexcept { return &m_value; }
            iterator& operator ++ () noexcept { ++m_value; return *this; }
    
            friend bool operator == (const iterator & a, const iterator b) noexcept {
                return a.m_value == b.m_value;
            }
            friend bool operator != (const iterator & a, const iterator b) noexcept {
                return a.m_value != b.m_value;
            }
    
            private:
            T m_value;
        };
    
        public:
        Range(const T& first, const T& last) noexcept
        :   m_first(first), m_last(last)
        {}
    
        Range(T&& first, T&& last) noexcept
        :   m_first(std::move(first)), m_last(std::move(last))
        {}
    
        Range(Range&& other) noexcept
        :   m_first(std::move(other.m_first)),
            m_last(std::move(other.m_last))
        {}
    
        Range& operator = (Range&& other) noexcept {
            m_first = std::move(other.m_first);
            m_last = std::move(other.m_last);
            return *this;
        }
    
        iterator begin() const noexcept { return  m_first; }
        iterator end() const noexcept { return m_last; }
    
        private:
        T m_first;
        T m_last;
    };
    
    template<typename T>
    inline Range<T> range(T&& first, T&& last) noexcept {
        return Range<T>(std::move(first), std::move(last));
    }
    
    
    // Test
    // ====
    
    #include <iostream>
    
    int main() {
        for(auto i : range(0, 3))
            std::cout << i << '\n';
    }
    

    A more sophisticated implementation would consider containers and iterators, too.