I'd like to define a concepts that is true if
- t.ok(c) compiles and returns a bool, where t is a template parameter of type T and c is a "concrete" type of type C
- t.around(c) compiles and returns something that can be iterated over (the type of each element is C)
So far, I wrote the following mwe, but can't get my head around it to make it work.
#include <iostream>
#include <concepts>
#include <ranges>
#include <array>
#include <vector>
using namespace std;
struct Integ
{
int val;
};
template<class Cont, class T>
concept range_of = std::ranges::range<Cont>
&& std::is_same_v<T, std::ranges::range_value_t<Cont>>;
template<class T, class Cont>
concept LookingRight = requires(const T& t, const Integ& i)
{
{ t.ok(i) } -> std::same_as<bool>; //ok if t.ok(i) compiles and returns bool
{ t.around(i) } -> range_of<Cont,Integ>; //ok it t.around(i) compiles and returns sth iterable
};
std::vector<Integ> filter(const auto& LookingRight lr, const Integ& i)
{ //probably a better way to filter with ranges
std::vector<Integ> v;
for(const Integ& ii : lr.around(i))
if(lr.ok(ii))
v.push_back(ii);
return v;
}
struct Even
{
bool ok(const Integ& i) const
{
return i.val % 2 == 0;
}
std::array<Integ,4> around(const Integ& i) const
{
return {Integ(i.val-2), Integ(i.val-1), Integ(i.val+1), Integ(i.val+2)};
}
};
int main()
{
Even e;
for(auto i : filter(e, {0}))
cout << i.val << " ";
cout << endl;
}
I have some questions :
- how to make it work, and what did I do wrong ?
- why do I have to write
-> std::same_as<bool>
and I can't just write-> bool
I'm compiling with g++ (Ubuntu 11.3.0-1ubuntu1~22.04) 11.3.0. as g++ -std=c++20 -o mwe mwe.cpp
The compiler tells me that range_of<Cont, Integ> doesn't name a type
(in the declaration of LookingRight). I also have syntax errors in the prototype of filter (I suspect they are there because LookingRight isn't properly defined)