#include <iostream>
#include <limits>
#include <type_traits>

using namespace std;

template<typename Arr>
auto maxValue(const Arr& a) -> typename remove_all_extents<Arr>::type
{
    static_assert(rank<Arr>::value,"[] type only :)");
    using T = typename remove_all_extents<Arr>::type;
    T res = numeric_limits<T>::min();
    if constexpr(rank<Arr>::value == 1)
    {
        for(int i = 0; i < extent<Arr>::value; ++i)
            if (res < a[i]) res = a[i];
    }
    else
    {
        for(int i = 0; i < extent<Arr>::value; ++i)
        {
            T val = maxValue(a[i]);
            if (res < val) res = val;
        }
    }
    return res;
}


int main(int argc, char * argv[])
{
    int a3[3][2][2] = {
        {{1,2},{3,4}},
        {{5,6},{7,8}},
        {{0,2},{2,4}},
    };
    int a1[5] = { 1, 5, 2, 9, 7 };

    cout << maxValue(a3) << endl;
    cout << maxValue(a1) << endl;
}
