re PR c++/69066 (SFINAE compilation error on lambda with trailing return type)
authorPaolo Carlini <paolo.carlini@oracle.com>
Sun, 10 Apr 2016 09:32:46 +0000 (09:32 +0000)
committerPaolo Carlini <paolo@gcc.gnu.org>
Sun, 10 Apr 2016 09:32:46 +0000 (09:32 +0000)
2016-04-10  Paolo Carlini  <paolo.carlini@oracle.com>

PR c++/69066
* g++.dg/cpp1y/pr69066.C: New.

From-SVN: r234869

gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp1y/pr69066.C [new file with mode: 0644]

index 9784a4b6f054d1e4a194e827a873613e58b53d9e..77b614b2db7331c36341808b99abd699fdb579a2 100644 (file)
@@ -1,3 +1,8 @@
+2016-04-10  Paolo Carlini  <paolo.carlini@oracle.com>
+
+       PR c++/69066
+       * g++.dg/cpp1y/pr69066.C: New.
+
 2016-04-09  Jerry DeLisle  <jvdelisle@gcc.gnu.org>
 
        PR fortran/68566
diff --git a/gcc/testsuite/g++.dg/cpp1y/pr69066.C b/gcc/testsuite/g++.dg/cpp1y/pr69066.C
new file mode 100644 (file)
index 0000000..263e1b6
--- /dev/null
@@ -0,0 +1,75 @@
+// PR c++/69066
+// { dg-do compile { target c++14 } }
+
+template <typename T> T&& declval();
+
+template<typename T, T v>
+struct integral_constant
+{
+  static constexpr T                value = v;
+  typedef T                         value_type;
+  typedef integral_constant<T, v>   type;
+  constexpr operator value_type() const { return value; }
+};
+
+typedef integral_constant<bool, true>     true_type;
+typedef integral_constant<bool, false>    false_type;
+
+template <typename...>
+using void_t = void;
+
+template <typename, typename = void>
+class is_zero_callable : public false_type
+{
+};
+
+template <typename T>
+class is_zero_callable<T, void_t<decltype(declval<T>()())>>
+    : public true_type
+{
+};
+
+template <typename TF, bool TLastStep>
+struct curry_impl
+{
+    static auto exec(TF f)
+    {
+        // Bind `x` to subsequent calls.
+        return [=](auto x)
+        {
+            auto bound_f = [=](auto... xs) -> decltype(f(x, xs...))
+            {
+                return f(x, xs...);
+            };
+
+            // Recursive step.
+            return curry_impl<decltype(bound_f),
+                is_zero_callable<decltype(bound_f)>{}>::exec(bound_f);
+        };
+    }
+};
+
+template <typename TF>
+struct curry_impl<TF, true>
+{
+    static auto exec(TF f)
+    {
+        return f();
+    }
+};
+
+template <typename TF>
+auto curry(TF f)
+{
+    return curry_impl<TF, is_zero_callable<decltype(f)>{}>::exec(f);
+}
+
+int main()
+{
+    auto sum = [](int x, int y)
+    {
+        return x + y;
+    };
+
+    (void)curry(sum)(1)(1);
+}