I have a type that is a template type, and a vector of said type
template<typename T>
struct result_t {
T value;
};
template<typename elem_type>
using list_t = std::vector<result_t<elem_type>>;
How do I define I generic function that is constrained to such a range?
Hard coded with just a vector:
template<typename elem_type>
auto values(const std::vector<result_t<elem_type>>& values) {...}
I would like to update my function to be generic, to take any type of range, even a view
template<typename range_t>
concept is_result_range = std::ranges::range<range_t> && ...;
template<is_result_range range_t>
auto values(const range_t& values) {...}
I have tried:
template<typename range_t, typename element_t>
concept is_result_range = std::ranges::range<range_t>
&& std::is_same_v<typename std::ranges::range_value_t<range_t>, result<element_t>>;
But the compiler is not happy since it can't deduce the template arguments.
You can use template specialization to detect that the value type of range is a specialization of result_t
#include <ranges>
template<typename T>
struct result_t {
T value;
};
template<typename T>
constexpr bool is_result_t = false;
template<typename T>
constexpr bool is_result_t<result_t<T>> = true;
template<typename range_t>
concept is_result_range = std::ranges::input_range<range_t>
&& is_result_t<std::ranges::range_value_t<range_t>>;
Then you can constrain the function as
template<is_result_range R>
auto values(R&& values) {
return values
| std::views::transform([](const auto& res) { return res.value; });
}