3
\$\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\$

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Browse other questions tagged or ask your own question.