#include <vector>
#include <iostream>

typedef std::vector<unsigned int> uint_vector;
typedef std::vector<uint_vector> values_vector;

values_vector all_values (const uint_vector & ranges, unsigned int pos=0) {
   values_vector result;
   if (pos == ranges.size()) {
      result.push_back (uint_vector());
   }   
   else {
      values_vector rem_result = all_values (ranges, pos+1);
      for (unsigned int v = 0; v < ranges[pos]; ++v) {
         for (auto it : rem_result) {
            result.push_back (uint_vector(1,v));
            result.back().insert (result.back().end(), it.begin(), it.end());
         }
      }   
   }   
   return result;
}

void print_values (const values_vector & combos) {
   for (auto combo : combos) {
      std::cout << "[ ";
      for (auto num : combo) {
         std::cout << num << ' ';
      }   
      std::cout << "]\n";
   }   
}

int main () {
   uint_vector ranges {3,2,2};
   print_values (all_values (ranges));
   return 0;
}