Hi Paul! Thanks for taking a look! Your library makes a very interesting proposition. Comments follow:
https://github.com/pfultz2/Tick
It supports gcc, clang, and MSVC, and has several already defined concept traits in the library(such as `is_container` or `is_iterator`). There is some more work that needs to be finished with the documentation. Once I finish work with the Fit library, I plan to finish up that library and submit it for formal review as well.
How did you get MSVC to work? Last time I tried to port my implementation I got stuck into a network of compiler crashes that I eventually assumed were due to the lack of proper expression SFINAE support and fundamentally unavoidable for such a library.
- It wants to be future-proof. Concepts defined with the `ABL_CONCEPT_SPEC` macro can be automatically upgraded to a Concepts Lite concept by redefining `ABL_CONCEPT` as `constexpr concept`.
Integral constants are more powerful and expressive than raw constexpr values.
An older version of my library was using integral constants too, but eventually I decided against it. Rationale: 1. this library wants to bring concepts to casual users of templates, not just metaprogrammers. constexpr functions might be easier to understand. 2. constexpr functions would users to the library get the benefits of real concepts straight away, once they are there. Again, this is specially important for the intended audience, that would benefit a lot from better error messages, etc. 3. something similar to the standard might help the standard committee in getting examples of practical use-cases. 3. integral-constant returning metafunctions can still be provided. In the library, the macro defines both `MyConcept` and `MyConcept_spec`, the later being usable with various metafunctions, giving that extra functionality to "power users".
Just some notes, you will get better error reporting from the compiler using `typename std::enable_if<(...)>::type` instead of using template aliases such as `enable_if_t`. Most compilers don't have the infrastucture to trace template aliases(and I don't think they will anytime soon). This is why libraries have a `REQUIRES` macro instead. In addition for the Tick library, it proved benifecial as it allowed to handle boolean expression that are not dependent on the deduced template parameter, workaround constexpr bugs on MSVC and better handle function overloading.
That's interesting! Is that what allowed you to get rid of the MSVC crashes? While in principle I am not fan of macros, specially when mixed in funny places of type declarations and signatures, a carefully designed REQUIRES macro may also provide a smooth C++-1N transition for concept clients...
Also, the Tick library doesn't use the `valid_expr(f(x))` to check valid expressions, because if `f` returns void then it will fail substitution which means the trait is false even though it is a valid expression. Instead, it follows the suggestion by Jamboree of using a template `valid<...>` instead.
Atria concepts use the sintax `(f(x), may_be_void)` when `f` is allowed to return void, `may_be_void` being an arbitrary int constexpr. There are trade-offs to each and can't judge now what is better. Cheers! JP