This is a follow-up question for the previous questions about recursive functions, including A Summation Function For Arbitrary Nested Vector Implementation In C++, A recursive_count_if Function For Various Type Arbitrary Nested Iterable Implementation in C++, A recursive_count_if Function with Specified value_type for Various Type Arbitrary Nested Iterable Implementation in C++, A recursive_count_if Function with Automatic Type Deducing from Lambda for Various Type Arbitrary Nested Iterable Implementation in C++ and A recursive_count_if Function with Unwrap Level for Various Type Arbitrary Nested Iterable Implementation in C++. In order to test these functions for arbitrary nested iterables, I am trying to implement some arbitrary nested iterable generators to construct nested std::vector
s and nested std::array
s with the given parameters. The generator for std::array
case is named n_dim_array_generator
and another generator for std::vector
is named n_dim_vector_generator
. After trying to use if constexpr
syntax in the previous question, I found that it is possible to use the similar technique in n_dim_array_generator
function and n_dim_vector_generator
function.
The usage description
For example, auto test_vector = n_dim_vector_generator<2, int>(1, 3);
is expected to create a "test_vector" object which type is std::vector<std::vector<int>>
. The content of this test_vector
should as same as the following code.
std::vector<int> vector1;
vector1.push_back(1);
vector1.push_back(1);
vector1.push_back(1);
std::vector<std::vector<int>> test_vector;
test_vector.push_back(vector1);
test_vector.push_back(vector1);
test_vector.push_back(vector1);
There are four key part in the usage n_dim_vector_generator<2, int>(1, 3)
. The first number 2
represents the nested layers, the second parameter int
represents the type of base elements, the third parameter 1
represents the input element which would be filled in, and the fourth parameter 3
represents the element count in each layer.
In the n_dim_array_generator
function, the first parameter also represents the nested layers, but the parameter which represents the element count in each layer has been moved into the second one. Then, the third parameter represents the type of base elements and the fourth parameter represents the input element which would be filled in.
The experimental implementation
The experimental implementation of n_dim_vector_generator
function and n_dim_array_generator
function:
template<std::size_t dim, class T>
auto n_dim_vector_generator(T input, std::size_t times)
{
if (dim < 0)
{
throw std::logic_error("Dimension can not be set less than 0");
}
if constexpr (dim == 0)
{
return input;
}
else
{
std::vector<decltype(n_dim_vector_generator<dim - 1>(input, times))> output;
for (size_t i = 0; i < times; i++)
{
output.push_back(n_dim_vector_generator<dim - 1>(input, times));
}
return output;
}
}
template<std::size_t dim, std::size_t times, class T>
auto n_dim_array_generator(T input)
{
if (dim < 0)
{
throw std::logic_error("Dimension can not be set less than 0");
}
if constexpr (dim == 0)
{
return input;
}
else
{
std::array<decltype(n_dim_array_generator<dim - 1, times>(input)), times> output;
for (size_t i = 0; i < times; i++)
{
output[i] = n_dim_array_generator<dim - 1, times>(input);
}
return output;
}
}
Test cases
The test cases of n_dim_vector_generator
function and n_dim_array_generator
function are as below.
// n_dim_vector_generator function usage with recursive_reduce function and recursive_count_if function
auto test_vector1 = n_dim_vector_generator<3, int>(3, 2);
std::cout << "recursive_reduce output: " << recursive_reduce(test_vector1, 0) << std::endl;
std::cout << "recursive_count_if output: " << recursive_count_if<3>(test_vector1, [](auto& i) {return i == 3; }) << std::endl;
// n_dim_array_generator function usage with recursive_reduce function and recursive_count_if function
auto test_array1 = n_dim_array_generator<3, 2, int>(3);
std::cout << "recursive_reduce output: " << recursive_reduce(test_array1, 0) << std::endl;
std::cout << "recursive_count_if output: " << recursive_count_if<3>(test_array1, [](auto& i) {return i == 3; }) << std::endl;
The output of this test is as follows.
recursive_reduce output: 24
recursive_count_if output: 8
recursive_reduce output: 24
recursive_count_if output: 8
All suggestions are welcome.
The summary information:
Which question it is a follow-up to?
A Summation Function For Arbitrary Nested Vector Implementation In C++,
A recursive_count_if Function For Various Type Arbitrary Nested Iterable Implementation in C++,
What changes has been made in the code since last question?
The
n_dim_vector_generator
function andn_dim_array_generator
function are the key part here.Why a new review is being asked for?
I am not sure if it is a good idea to throw
std::logic_error
in the situation ofDimension is set less than 0
. If there is any further possible improvement, please let me know.