Closed ericniebler closed 9 years ago
Just for fun, find_index
with let
:
template<typename T, typename List>
using find_index = let<
var<_a, find<List, T>>,
lazy::if_<
std::is_same<_a, list<>>,
meta::npos,
lazy::minus<size<List>, lazy::size<_a>>>>;
You are just showing off, come on, admit it.
On Thu, Feb 26, 2015 at 10:30 PM, Eric Niebler notifications@github.com wrote:
Just for fun, find_index with let:
template<typename T, typename List>using find_index = let< var<a, find<List, T>>, lazy::if< std::is_same<_a, list<>>, meta::npos, lazy::minus<size
, lazy::size<_a>>>>;
— Reply to this email directly or view it on GitHub https://github.com/ericniebler/meta/issues/13#issuecomment-76277714.
You know you want it.
This meta library is cool, and newbies like me can learn alot from the implementations: 2 questions: what is the
void_<C<eval<impl<Ts, Args>>...>>
in the lambda implementation, this evaluates always to void right? is that somehow to enforce pattern matching =) or to trick the compiler to know something beforhand or is it SFINAE?
thanks :-)
It's SFINAE. That specialization will only be selected if C<eval<impl<Ts, Args>>...>
is well-formed.
There's a lot about Meta's implementation that is not obvious. I could write an entire blog post about the implementation of meta::quote
, for instance:
template<template<typename...> class C>
struct quote
{
private:
template<typename, typename = quote, typename = void>
struct impl
{};
template<typename...Ts, template<typename...> class D>
struct impl<list<Ts...>, quote<D>, void_<D<Ts...>>>
{
using type = D<Ts...>;
};
public:
// Indirection here needed to avoid Core issue 1430
// http://open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1430
template<typename...Ts>
using apply = eval<impl<list<Ts...>>>;
};
Currently, clang is the only compiler that gets it 100% correct. (I have reason to think gcc-5 will get it right, too.) This part of the C++ standard is very underspecified, so I can't be completely sure this is "right", or even that the committee knows what "right" should be here.
What I'm saying is, there's a lot you won't get just by studying Meta's implementation. I would need to document it.
Fixed in 4822936
once you have little time, it would be a lot usefull to read a post about these subtle things, like meta::quote or so :-)
under the hood there is some much involved. when I see the intricacies and all the workarounds in c++ especially with templates I am always asking my self is this language not gone over board a long time ago :) but I like it, its fast and cool :-) and it makes you think a little bit (as a beginner im templates) about what the compiler can do and what it can simply not guess =)
thanks for the good work =)
Am 28.02.2015 um 03:22 schrieb Eric Niebler notifications@github.com:
Closed #13.
— Reply to this email directly or view it on GitHub.
For the record, I've discovered something very interesting about let
and defer
. Since they (and lambda
) do SFINAE consistently and turn into a no-op when any substitution failure occurs, they can be used to do compile-time computations that can fail. Consider:
// This might or might not have a nested ::type typedef
template<typename T>
struct difference_type
: detail::difference_type<uncvref_t<T>>
{};
template<typename T>
struct size_type
: std::make_unsigned<meta::eval<difference_type<T>>>
{};
difference_type
may or may not have a nested ::type
, but size_type
acts like the nested ::type
is always there and issues a hard error when it's not. size_type
could instead be written like this:
template<typename T>
struct size_type
: meta::lazy::let<std::make_unsigned<meta::lazy::eval<difference_type<T>>>>
{};
Now size_type
only has a nested ::type
if difference_type
does, too.
[*] This only works on clang at the moment. Gcc has a bug that will supposedly be fixed for 5.0.
[...] let and defer. Since they (and lambda) do SFINAE consistently and turn into a no-op when any substitution failure occurs
What is the best way to detect if an error occurred?
Not sure I understand the question. If an error occurred where?
Not sure I understand the question. If an error occurred where?
I think what Gonzalo is referring to is how can we tell why the metafunction can't be called, since this produces a similiar problem to using a trailing decltype as well.
If you're getting a substitution failure trying to apply a metafunction, you have to move the logic of your metafunction to a non-immediate context, where it will cause a hard error with a backtrace.
In ericniebler/range-v3@970ce2e, I added
meta::count
,meta::count_if
, andmeta::let
. These need to be merged.