1
\$\begingroup\$

This is a follow-up question for A recursive_transform for std::vector with various return type and A recursive_transform for std::array with various return type. Based on these discussion about the recursive things, the another idea comes up in my mind that trying to implement a print function for arbitrary nested iterable things. Normally, the multiple for loops may be used for printing nested iterables. Maybe like this one.

std::vector<double> testVector1;
testVector1.push_back(1);
testVector1.push_back(20);
testVector1.push_back(-100);

decltype(testVector1) testVector2;
testVector2.push_back(10);
testVector2.push_back(90);
testVector2.push_back(-30);

std::vector<decltype(testVector1)> testVector3;
testVector3.push_back(testVector1);
testVector3.push_back(testVector2);

for (auto& outer_element : testVector3)
{
    for (auto& inner_element : outer_element)
    {
        std::cout << inner_element << std::endl;
    }
}

However, the multiple nested for loop shows up when it comes to the case like std::vector<std::vector<std::vector<std::vector<...>>>>.

If the structure similar to recursive_transform is used in this task, that's the recursive_print function here.

template<typename T>
concept is_iterable = requires(T x)
{
    *std::begin(x);
    std::end(x);
};

template<typename T>
concept is_elements_iterable = requires(T x)
{
    std::begin(x)->begin();
    std::end(x)->end();
};

template<class T> requires is_iterable<T>
T recursive_print(const T& input, const int level = 0)
{
    T output = input;
    std::cout << std::string(level, ' ') << "Level " << level << ":" << std::endl;
    std::transform(input.cbegin(), input.cend(), output.begin(), 
        [level](auto& x)
        {
            std::cout << std::string(level, ' ') << x << std::endl;
            return x;
        }
    );
    return output;
}

template<class T> requires is_iterable<T> && is_elements_iterable<T>
T recursive_print(const T& input, const int level = 0)
{
    T output = input;
    std::cout << std::string(level, ' ') << "Level " << level << ":" << std::endl;
    std::transform(input.cbegin(), input.cend(), output.begin(),
        [level](auto& element)
        {
            return recursive_print(element, level + 1);
        }
    );
    return output;
}

Here's a Godbolt link. The output of the example is as below. The nested level is also displaying with this recursive_print function.

Level 0:
 Level 1:
  Level 2:
  1
  20
  -100
  Level 2:
  10
  90
  -30
 Level 1:
  Level 2:
  1
  20
  -100
  Level 2:
  10
  90
  -30

All suggestions are welcome.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.