public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Lambda templates and implicit function templates.
@ 2013-08-11 19:50 Adam Butcher
  2013-08-11 19:50 ` [PATCH 1/3] Support lambda templates Adam Butcher
                   ` (2 more replies)
  0 siblings, 3 replies; 21+ messages in thread
From: Adam Butcher @ 2013-08-11 19:50 UTC (permalink / raw)
  To: Jason Merrill; +Cc: gcc-patches, Gabriel Dos Reis, Andrew Sutton, Adam Butcher

Hi Jason,

I decided to go ahead and submit the latest cleaned up version of the generic
lambda and implicit function template patches.  I think all review comments have
been addressed.  As well as the cleanup there are a few enhancements; generic
lambda instantiations in diagnostics now show template argument bindings and the
appropriate -std=xxx guards have been put in place.  I've also fixed a couple of
cases where invalid user code caused an ICE.

I am yet to write some tests for individual features to be included in the
source tree but intend to when I get some more time.  In the meantime I've
included the two main tests I've used for trials.

Cheers,
Adam

--------------------------------
Patch summary (3):

  Support lambda templates.
  Support using 'auto' in a function parameter list to introduce an
    implicit template parameter.
  Support dumping type bindings in lambda diagnostics.

 gcc/cp/cp-tree.h |  11 ++++
 gcc/cp/decl.c    |  19 +++++-
 gcc/cp/decl2.c   |   5 +-
 gcc/cp/error.c   |  22 +++----
 gcc/cp/lambda.c  |  87 +++++++++++++++++++------
 gcc/cp/parser.c  |  98 +++++++++++++++++++++++++---
 gcc/cp/pt.c      | 193 ++++++++++++++++++++++++++++++++++++++++++++++++++-----
 7 files changed, 375 insertions(+), 60 deletions(-)

--------------------------------
Basic compile and runtime check:

   /* Implicit function templates at namespace scope.  */
   
   auto f1 (auto& a, auto const& b) { return a += b; }
   
   template <typename A>
   auto f2 (A& a, auto const& b) { return a += b; }
   
   template <typename B>
   auto f3 (auto& a, B const& b) { return a += b; }
   
   template <typename A, typename B>
   auto f4 (A& a, B const& b) { return a += b; }
   
   
   struct S
   {
     /* Implicit non-static member function templates.  */
   
     auto mf1 (auto& a, auto const& b) { return a += b; }
   
     template <typename A>
     auto mf2 (A& a, auto const& b) { return a += b; }
   
     template <typename B>
     auto mf3 (auto& a, B const& b) { return a += b; }
   
     template <typename A, typename B>
     auto mf4 (A& a, B const& b) { return a += b; }
   
     /* Implicit static member function templates.  */
   
     static auto smf1 (auto& a, auto const& b) { return a += b; }
   
     template <typename A>
     static auto smf2 (A& a, auto const& b) { return a += b; }
   
     template <typename B>
     static auto smf3 (auto& a, B const& b) { return a += b; }
   
     template <typename A, typename B>
     static auto smf4 (A& a, B const& b) { return a += b; }
   };
   
   
   #undef NDEBUG
   #include <cassert>
   
   
   #define CHECK(A, b, f) do {      \
      A a1 = 5, a2 = 12;            \
      auto r1 = f (a1, b);          \
      auto r2 = f (a2, b);          \
      assert ((#f, a1 == 5 + b));   \
      assert ((#f, a2 == 12 + b));  \
      assert ((#f, r1 == a1));      \
      assert ((#f, r2 == a2));      \
   } while (0)
   
   #define INVOKEi(f, A, b, i) do { CHECK (A, b, f ## i); } while (0)
   #define INVOKE4(f, A, b) do { INVOKEi (f, A, b, 1); \
   			         INVOKEi (f, A, b, 2); \
   			         INVOKEi (f, A, b, 3); \
   			         INVOKEi (f, A, b, 4); } while (0)
   
   #define AS_FUNi(f, A, b, i) do { CHECK (A, b, f ## i._FUN); } while (0)
   #define AS_FUN4(f, A, b) do { AS_FUNi (f, A, b, 1); \
   			         AS_FUNi (f, A, b, 2); \
   			         AS_FUNi (f, A, b, 3); \
   			         AS_FUNi (f, A, b, 4); } while (0)
   
   #define AS_PTRi(f, A, B, b, i) do { A (*pfn) (A&, B const&) = f ## i; \
   				    CHECK (A, b, pfn); } while (0)
   #define AS_PTR4(f, A, B, b) do { AS_PTRi (f, A, B, b, 1); \
   				    AS_PTRi (f, A, B, b, 2); \
   				    AS_PTRi (f, A, B, b, 3); \
   				    AS_PTRi (f, A, B, b, 4); } while (0)
   
   
   int main()
   {
     /* Check namespace templates.  */
   
     INVOKE4 (f, float, 7);
     AS_PTR4 (f, float, int, 7);
   
     /* Check member templates.  */
   
     S s;
     INVOKE4 (s.mf, float, 7);
     INVOKE4 (s.smf, float, 7);
     INVOKE4 (S::smf, float, 7);
     AS_PTR4 (s.smf, float, int, 7);
     AS_PTR4 (S::smf, float, int, 7);
   
     /* Regression check non-template stateless lambda and its conversion
        to function pointer.  */
   
     auto lf0 = [] (float& a, int const& b) { return a += b; };
   
     INVOKEi (lf, float, 7, 0);
     AS_FUNi (lf, float, 7, 0);
     AS_PTRi (lf, float, int, 7, 0);
   
     /* Check stateless lambda templates.  */
   
     auto lf1 = [] (auto& a, auto const& b) { return a += b; };
     auto lf2 = [] <typename A> (A& a, auto const& b) { return a += b; };
     auto lf3 = [] <typename B> (auto& a, B const& b) { return a += b; };
     auto lf4 = [] <typename A, typename B> (A& a, B const& b) { return a += b; };
   
     INVOKE4 (lf, float, 7);
     AS_FUN4 (lf, float, 7);
     AS_PTR4 (lf, float, int, 7);
   
     /* Check capturing lambda templates.  */
   
     int i;
   
     auto lc1 = [i] (auto& a, auto const& b) { return a += b; };
     auto lc2 = [i] <typename A> (A& a, auto const& b) { return a += b; };
     auto lc3 = [i] <typename B> (auto& a, B const& b) { return a += b; };
     auto lc4 = [i] <typename A, typename B> (A& a, B const& b) { return a += b; };
   
     INVOKE4 (lc, float, 7);
   }

--------------------------------
Dependent type check:

   struct S
   {
      struct N
      {
         float test () {}
      };
   };
   
   int main()
   {
      auto f = [] <typename T> (T const& s) {
         typename T::N x;
         return x.test ();
      };
      auto g = [] (auto const& s) {
         typename std::decay<decltype (s)>::type::N x;
         return x.test ();
      };
   
      S i;
      f(i);
      g(i);
   
      float (*pfn) (S const&) = f;
   
      pfn(i);
   
      pfn = g;
   
      return pfn(i);
   }

-- 
1.8.3

^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2013-08-29 19:34 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-08-11 19:50 Lambda templates and implicit function templates Adam Butcher
2013-08-11 19:50 ` [PATCH 1/3] Support lambda templates Adam Butcher
2013-08-12 15:47   ` Jason Merrill
2013-08-12 23:52     ` Adam Butcher
2013-08-13 12:29       ` Jason Merrill
2013-08-11 19:50 ` [PATCH 3/3] Support dumping type bindings in lambda diagnostics Adam Butcher
2013-08-27 16:57   ` Jason Merrill
2013-08-27 19:43     ` Adam Butcher
2013-08-28  3:02       ` Jason Merrill
2013-08-28  9:08         ` [PATCH] Support dumping type bindings and 'mutable' qualifier " Adam Butcher
2013-08-28 12:57           ` Gabriel Dos Reis
2013-08-29 15:15             ` Adam Butcher
2013-08-29 15:57               ` Gabriel Dos Reis
2013-08-29 18:24                 ` Adam Butcher
2013-08-29 18:51                   ` Adam Butcher
2013-08-29 19:38                     ` Gabriel Dos Reis
2013-08-11 19:50 ` [PATCH 2/3] Support using 'auto' in a function parameter list to introduce an implicit template parameter Adam Butcher
2013-08-12 16:52   ` Jason Merrill
2013-08-13  0:34     ` Adam Butcher
2013-08-14 14:07       ` Jason Merrill
2013-08-14 14:29         ` Gabriel Dos Reis

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).