2
\$\begingroup\$

This is a follow-up question for A recursive_count Function with Unwrap Level for Various Type Arbitrary Nested Iterable Implementation in C++. A function recursive_depth for calculating depth of nested iterables is mentioned in G. Sliepen's answer. I am trying to implement recursive_depth function in this post.

  • Given non-nested types char, int, the outputs of recursive_depth template function are 0.

  • Given nested types such as std::vector<int>, std::deque<int> and std::list<int>, the outputs of recursive_depth template function are 1.

  • Given nested types such as std::vector<std::vector<int>>, std::deque<std::deque<int>> and std::list<std::list<int>>, the outputs of recursive_depth template function are 2.

The experimental implementation

  • recursive_depth function implementation

    //  recursive_depth function implementation
    template<typename T>
    constexpr std::size_t recursive_depth()
    {
        return 0;
    }
    
    template<std::ranges::input_range Range>
    constexpr std::size_t recursive_depth()
    {
        return recursive_depth<std::ranges::range_value_t<Range>>() + 1;
    }
    

The testing code

The non-nested type char, non-nested type int, std::vector<int>, std::vector<std::vector<int>>, std::deque<int>, std::deque<std::deque<int>>, std::list<int> and std::list<std::list<int>> are tested.

void recursive_depth_test();

int main()
{
    recursive_depth_test();
}

void recursive_depth_test()
{
    //  non-nested type `char`
    char test_char = 'A';
    std::cout << recursive_depth<decltype(test_char)>() << '\n';
    
    //  non-nested type `int`
    int test_int = 100;
    std::cout << recursive_depth<decltype(test_int)>() << '\n';
    
    //  std::vector<int>
    std::vector<int> test_vector{ 5, 7, 4, 2, 8, 6, 1, 9, 0, 3 };
    std::cout << recursive_depth<decltype(test_vector)>() << '\n';

    //  std::vector<std::vector<int>>
    std::vector<decltype(test_vector)> test_vector2{ test_vector , test_vector , test_vector };
    std::cout << recursive_depth<decltype(test_vector2)>() << '\n';

    //  std::deque<int>
    std::deque<int> test_deque;
    test_deque.push_back(1);
    test_deque.push_back(2);
    test_deque.push_back(3);
    test_deque.push_back(4);
    test_deque.push_back(5);
    test_deque.push_back(6);
    std::cout << recursive_depth<decltype(test_deque)>() << '\n';

    //  std::deque<std::deque<int>>
    std::deque<decltype(test_deque)> test_deque2;
    test_deque2.push_back(test_deque);
    test_deque2.push_back(test_deque);
    test_deque2.push_back(test_deque);
    std::cout << recursive_depth<decltype(test_deque2)>() << '\n';

    //  std::list<int>
    std::list<int> test_list = { 1, 2, 3, 4, 5, 6 };
    std::cout << recursive_depth<decltype(test_list)>() << '\n';


    //  std::list<std::list<int>>
    std::list<std::list<int>> test_list2 = { test_list, test_list, test_list, test_list };
    std::cout << recursive_depth<decltype(test_list2)>() << '\n';
}

The output of the testing code above:

0
0
1
2
1
2
1
2

A Godbolt link is here.

All suggestions are welcome.

The summary information:

\$\endgroup\$
1
\$\begingroup\$

The implementation is straightforward and correct as far as I can tell.

What would you expect the output of std::vector<std::string> case?

I expect it to be 2, as both std::vector and std::string are ranges. We have had this discussion before, and in case you want to have recursion stop when reaching a certain type, you might want to introduce another template, perhaps named recursive_depth_until.

\$\endgroup\$

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.