
What is the added value of your library respect to Eric work?
Its actually based on Eric Niebler's framework. Now there is a lot of details about it that I don't know, since it is mostly undocumeted. In his framework, an `Incrementable` concept would be built like this: struct Incrementable { template<class T> auto requires(T&& x) -> decltype(concepts::valid_expr( (x++, 42), ++x )); }; template<class T> using is_incrementable = concept::models<Incrementable, T>; The whole `42` is needed to avoid problems if `x++` returns `void`. In Tick, `is_incrementable` can be defined in a similiar manner: struct Incrementable : tick::ops { template<class T> auto requires(T&& x) -> TICK_VALID( x++, ++x ); }; template<class T> using is_incrementable = tick::trait<Incrementable(T)>; Now, the biggest difference is the `TICK_VALID` macro which works around the returning `void` problem, so I don't need to use the `42` hack. The second difference is that I call `tick::trait` rather than `concept::models`, but they work in a similiar manner(perhaps it would make send to rename it to `models`). Now I feel there is a decent amount of boilerplate using ` tick::trait`(or `concept::models`), so the `TICK_TRAIT` macro just simplifies that process. Next, in Eric Niebles's framework as well in Tick, refinements to traits can be defined. So if we want `is_incrementable` to also be copyable, we need to define a `CopyConstructible` concept and then refine it, something like this(I could be wrong about some of these details): struct CopyConstructible { template<class T> auto requires(T&& x) -> decltype(concepts::valid_expr( concepts::is_true(std::is_copy_constuctible<T>{}) )); }; struct Incrementable : refines<CopyConstructible> { template<class T> auto requires(T&& x) -> decltype(concepts::valid_expr( (x++, 42), ++x )); }; template<class T> using is_incrementable = concept::models<Incrementable, T>; In Tick, we use placeholder expressions to define refinements from other traits. We also aren't restricted to just concepts, so we can reuse other traits(such as `std::is_copy_constructible`), so in Tick we would just simply define: struct Incrementable : tick::refines<std::is_copy_constructible<tick::_>>, tick::ops { template<class T> auto requires(T&& x) -> TICK_VALID( x++, ++x ); }; template<class T> using is_incrementable = tick::trait<Incrementable(T)>; Also, refinements can be added to the macro version as well: TICK_TRAIT(is_incrementable, std::is_copy_constructible<_>) { template<class T> auto requires(T&& x) -> TICK_VALID( x++, ++x ); }; Notice we don't need the `tick::` namespace for the placeholders anymore. Also, tick provides `TICK_TRAIT_CHECK` which will output to the compiler all that traits that failed including any traits that were refined(ie base traits). Also, types can be matched against other traits using placeholder expressions, so if we want `some_trait` that checks if `x.foo()` is a fusion sequence, we would just do this: TICK_TRAIT(some_trait) { template<class T> auto requires(T&& x) -> TICK_VALID( returns<boost::fusion::is_sequence<_>>(x.foo()) ); }; Something similiar can be done in Eric's framework but it would require wrapping `boost::fusion::is_sequence` in a concept, something like this: struct FusionSequence { template<class T> auto requires(T&& x) -> decltype(concepts::valid_expr( concepts::is_true(boost::fusion::is_sequence<T>{}) )); }; struct SomeConcept { template<class T> auto requires(T&& x) -> decltype(concepts::valid_expr( concept::model_of<FusionSequence>(x.foo()) )); }; template<class T> using some_trait = tick::trait<SomeConcept(T)>; Finally, I don't support adding nested types, like in the example you gave with `Addable::result_t`: struct Addable { template<typename T, typename U> using result_t = decltype(std::declval<T>() + std::declval<U>()); template<typename T> auto requires(T && t) -> decltype(concepts::valid_expr( t + t )); template<typename T, typename U> auto requires(T && t, U && u) -> decltype(concepts::valid_expr( t + u )); }; In practice, I find it better to write a separate trait(or metafunction) for this. It provides better reusability and composability. It seems the C++ community has already progressed in this direction as we have moved from using `iterator_traits<T>::reference` to using `iterator_reference<T>::type`. I could add the ability to make this usable in Tick if there was a real need for it. -- View this message in context: http://boost.2283326.n4.nabble.com/Tick-Trait-instrospection-library-for-C-1... Sent from the Boost - Dev mailing list archive at Nabble.com.