Search code examples
c++loopsfor-loopsyntaxtranslate

One-liner for nested for loops in C++


In Python I can do this:

>>> import itertools
>>> for i, j,  in itertools.product(range(3), repeat=2): print i, j
...
0 0
0 1
0 2
1 0
1 1
1 2
2 0
2 1
2 2

Is it possible to have an easy-to-read, non-boost version of this in C++?


Solution

  • Looping example (updated):

    #include <array>
    #include <iostream>
    #include <utility>
    
    template<int VRange, int VRepCount, int VValueRIndex = VRepCount> class
    t_Looper
    {
        public: template<typename TAction> static void
        process(::std::array<int, VRepCount> & values, TAction && action)
        {
            for(;;)
            {
                t_Looper<VRange, VRepCount, VValueRIndex - 1>::process(values, ::std::forward<TAction>(action));
                auto & value{values[VRepCount - VValueRIndex]};
                if((VRange - 1) != value)
                {
                    ++value;
                }
                else
                {
                    value = 0;
                    break;
                }
            }
        }
    };
    
    template<int VRange, int VRepCount> class
    t_Looper<VRange, VRepCount, 0>
    {
        private: template<int... VIndexes, typename TAction> static void
        invoke(::std::integer_sequence<int, VIndexes...>, ::std::array<int, VRepCount> const & values, TAction && action)
        {
            action(values[VIndexes]...);
        }
    
        public: template<typename TAction> static void
        process(::std::array<int, VRepCount> & values, TAction && action)
        {
            invoke(::std::make_integer_sequence<int, VRepCount>(), values, ::std::forward<TAction>(action));
        }
    };
    
    template<int VRange, int VRepCount, typename TAction> void
    multiloop(TAction && action)
    {
        ::std::array<int, VRepCount> values{};
        t_Looper<VRange, VRepCount>::process(values, ::std::forward<TAction>(action));
    }
    
    int main()
    {
        multiloop<3, 2>([](int i, int j){::std::cout << i << " " << j << ::std::endl;});
        multiloop<3, 4>([](int i, int j, int k, int l){::std::cout << i << " " << j << " " << k << " " << l << ::std::endl;});
        return(0);
    }
    

    Run this code online