]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/9737 ([DR150] Partial template specialisation selection failure involving...
authorMark Mitchell <mark@codesourcery.com>
Tue, 7 Feb 2006 11:11:30 +0000 (11:11 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Tue, 7 Feb 2006 11:11:30 +0000 (11:11 +0000)
PR c++/9737
* pt.c (coerce_template_template_parms): Do not templates with
excess default arguments to match template template parameters
with fewer parameters.
(coerce_template_parms): Add use_default_args parameter; use
default arguments only when true.
(lookup_template_class): Adjust call to coerce_template_parms.
(fn_type_unification): Likewise.
(unify): Likewise.
(get_bindings): Likewise.
(dependent_type_p): Add assertions.

PR c++/9737
* g++.dg/template/ttp15.C: New test.
* g++.dg/template/ttp16.C: Likewise.
* g++.dg/template/ttp17.C: Likewise.
* g++.old-deja/g++.pt/ttp36.C: Remove.
* g++.old-deja/g++.pt/ttp19.C: Likewise.
* g++.old-deja/g++.pt/ttp37.C: Likewise.
* g++.old-deja/g++.pt/ttp38.C: Likewise.
* g++.old-deja/g++.pt/ttp39.C: Likewise.
* g++.old-deja/g++.pt/ttp9.C: Likewise.
* g++.old-deja/g++.pt/ttp40.C: Likewise.
* g++.old-deja/g++.pt/ttp51.C: Likewise.
* g++.old-deja/g++.pt/ttp26.C: Likewise.
* g++.old-deja/g++.pt/ttp36.C: Likewise.

* testsuite/testsuite_tr1.h (test_property): New function.
* testsuite/tr1/4_metaprogramming/type_properties/extent/extent.cc
(test01)

From-SVN: r110693

19 files changed:
gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/ttp15.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/ttp16.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/ttp17.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.pt/ttp19.C [deleted file]
gcc/testsuite/g++.old-deja/g++.pt/ttp26.C [deleted file]
gcc/testsuite/g++.old-deja/g++.pt/ttp35.C [deleted file]
gcc/testsuite/g++.old-deja/g++.pt/ttp36.C [deleted file]
gcc/testsuite/g++.old-deja/g++.pt/ttp37.C [deleted file]
gcc/testsuite/g++.old-deja/g++.pt/ttp38.C [deleted file]
gcc/testsuite/g++.old-deja/g++.pt/ttp39.C [deleted file]
gcc/testsuite/g++.old-deja/g++.pt/ttp40.C [deleted file]
gcc/testsuite/g++.old-deja/g++.pt/ttp51.C [deleted file]
gcc/testsuite/g++.old-deja/g++.pt/ttp9.C [deleted file]
libstdc++-v3/ChangeLog
libstdc++-v3/testsuite/testsuite_tr1.h
libstdc++-v3/testsuite/tr1/4_metaprogramming/type_properties/extent/extent.cc

index 18da1285724a01e7ec6c360e6e38e18bb5cb82b1..cdfeaf33d1e3446ff18289da598cb56bd31d7b7d 100644 (file)
@@ -1,3 +1,17 @@
+2006-02-07  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/9737
+       * pt.c (coerce_template_template_parms): Do not templates with
+       excess default arguments to match template template parameters
+       with fewer parameters.
+       (coerce_template_parms): Add use_default_args parameter; use
+       default arguments only when true.
+       (lookup_template_class): Adjust call to coerce_template_parms.
+       (fn_type_unification): Likewise.
+       (unify): Likewise.
+       (get_bindings): Likewise.
+       (dependent_type_p): Add assertions.
+
 2006-02-06  Roger Sayle  <roger@eyesopen.com>
 
        * decl.c (grokdeclarator): Don't bother checking for CHAR_TYPE.
index aac7f3ca22a990ade7b1508b36159de483a1beba..b1da4af144c638159d552b24462a535b61ee46f5 100644 (file)
@@ -102,7 +102,8 @@ static tree classtype_mangled_name (tree);
 static char* mangle_class_name_for_template (const char *, tree, tree);
 static tree tsubst_initializer_list (tree, tree);
 static tree get_class_bindings (tree, tree, tree);
-static tree coerce_template_parms (tree, tree, tree, tsubst_flags_t, int);
+static tree coerce_template_parms (tree, tree, tree, tsubst_flags_t, 
+                                  bool, bool);
 static void tsubst_enum        (tree, tree, tree);
 static tree add_to_template_args (tree, tree);
 static tree add_outermost_template_args (tree, tree);
@@ -3718,17 +3719,12 @@ convert_nontype_argument (tree type, tree expr)
    vectors of TREE_LIST nodes containing TYPE_DECL, TEMPLATE_DECL
    or PARM_DECL.
 
-   ARG_PARMS may contain more parameters than PARM_PARMS.  If this is
-   the case, then extra parameters must have default arguments.
-
    Consider the example:
-     template <class T, class Allocator = allocator> class vector;
-     template<template <class U> class TT> class C;
+     template <class T> class A;
+     template<template <class U> class TT> class B;
 
-   C<vector> is a valid instantiation.  PARM_PARMS for the above code
-   contains a TYPE_DECL (for U),  ARG_PARMS contains two TYPE_DECLs (for
-   T and Allocator) and OUTER_ARGS contains the argument that is used to
-   substitute the TT parameter.  */
+   For B<A>, PARM_PARMS are the parameters to TT, while ARG_PARMS are
+   the parameters to A, and OUTER_ARGS contains A.  */
 
 static int
 coerce_template_template_parms (tree parm_parms,
@@ -3746,10 +3742,7 @@ coerce_template_template_parms (tree parm_parms,
   nparms = TREE_VEC_LENGTH (parm_parms);
   nargs = TREE_VEC_LENGTH (arg_parms);
 
-  /* The rule here is opposite of coerce_template_parms.  */
-  if (nargs < nparms
-      || (nargs > nparms
-         && TREE_PURPOSE (TREE_VEC_ELT (arg_parms, nparms)) == NULL_TREE))
+  if (nargs != nparms)
     return 0;
 
   for (i = 0; i < nparms; ++i)
@@ -3988,17 +3981,20 @@ convert_template_argument (tree parm,
    arguments.  If any error occurs, return error_mark_node. Error and
    warning messages are issued under control of COMPLAIN.
 
-   If REQUIRE_ALL_ARGUMENTS is nonzero, all arguments must be
-   provided in ARGLIST, or else trailing parameters must have default
-   values.  If REQUIRE_ALL_ARGUMENTS is zero, we will attempt argument
-   deduction for any unspecified trailing arguments.  */
+   If REQUIRE_ALL_ARGS is false, argument deduction will be performed
+   for arugments not specified in ARGS.  Otherwise, if
+   USE_DEFAULT_ARGS is true, default arguments will be used to fill in
+   unspecified arguments.  If REQUIRE_ALL_ARGS is true, but
+   USE_DEFAULT_ARGS is false, then all arguments must be specified in
+   ARGS.  */
 
 static tree
 coerce_template_parms (tree parms,
                       tree args,
                       tree in_decl,
                       tsubst_flags_t complain,
-                      int require_all_arguments)
+                      bool require_all_args,
+                      bool use_default_args)
 {
   int nparms, nargs, i, lost = 0;
   tree inner_args;
@@ -4011,8 +4007,9 @@ coerce_template_parms (tree parms,
 
   if (nargs > nparms
       || (nargs < nparms
-         && require_all_arguments
-         && TREE_PURPOSE (TREE_VEC_ELT (parms, nargs)) == NULL_TREE))
+         && require_all_args
+         && (!use_default_args
+             || !TREE_PURPOSE (TREE_VEC_ELT (parms, nargs)))))
     {
       if (complain & tf_error)
        {
@@ -4039,7 +4036,7 @@ coerce_template_parms (tree parms,
       /* Calculate the Ith argument.  */
       if (i < nargs)
        arg = TREE_VEC_ELT (inner_args, i);
-      else if (require_all_arguments)
+      else if (require_all_args)
        /* There must be a default arg in this case.  */
        arg = tsubst_template_arg (TREE_PURPOSE (parm), new_args,
                                   complain, in_decl);
@@ -4444,7 +4441,9 @@ lookup_template_class (tree d1,
        arglist = add_to_template_args (current_template_args (), arglist);
 
       arglist2 = coerce_template_parms (parmlist, arglist, template,
-                                       complain, /*require_all_args=*/1);
+                                       complain, 
+                                       /*require_all_args=*/true,
+                                       /*use_default_args=*/true);
       if (arglist2 == error_mark_node
          || (!uses_template_parms (arglist2)
              && check_instantiated_args (template, arglist2, complain)))
@@ -4513,7 +4512,9 @@ lookup_template_class (tree d1,
            {
              tree a = coerce_template_parms (TREE_VALUE (t),
                                              arglist, template,
-                                             complain, /*require_all_args=*/1);
+                                             complain, 
+                                             /*require_all_args=*/true,
+                                             /*use_default_args=*/true);
 
              /* Don't process further if one of the levels fails.  */
              if (a == error_mark_node)
@@ -4542,7 +4543,9 @@ lookup_template_class (tree d1,
          = coerce_template_parms (INNERMOST_TEMPLATE_PARMS (parmlist),
                                   INNERMOST_TEMPLATE_ARGS (arglist),
                                   template,
-                                  complain, /*require_all_args=*/1);
+                                  complain, 
+                                  /*require_all_args=*/true,
+                                  /*use_default_args=*/true);
 
       if (arglist == error_mark_node)
        /* We were unable to bind the arguments.  */
@@ -9237,7 +9240,8 @@ fn_type_unification (tree fn,
       converted_args
        = (coerce_template_parms (DECL_INNERMOST_TEMPLATE_PARMS (fn),
                                  explicit_targs, NULL_TREE, tf_none,
-                                 /*require_all_arguments=*/0));
+                                 /*require_all_args=*/false,
+                                 /*use_default_args=*/false));
       if (converted_args == error_mark_node)
        return 1;
 
@@ -10003,21 +10007,44 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
            return 1;
 
          {
-           tree parmtmpl = TYPE_TI_TEMPLATE (parm);
            tree parmvec = TYPE_TI_ARGS (parm);
            tree argvec = INNERMOST_TEMPLATE_ARGS (TYPE_TI_ARGS (arg));
            tree argtmplvec
              = DECL_INNERMOST_TEMPLATE_PARMS (TYPE_TI_TEMPLATE (arg));
            int i;
 
-           /* The parameter and argument roles have to be switched here
-              in order to handle default arguments properly.  For example,
-              template<template <class> class TT> void f(TT<int>)
-              should be able to accept vector<int> which comes from
-              template <class T, class Allocator = allocator>
-              class vector.  */
+           /* The resolution to DR150 makes clear that default
+              arguments for an N-argument may not be used to bind T
+              to a template template parameter with fewer than N
+              parameters.  It is not safe to permit the binding of
+              default arguments as an extension, as that may change
+              the meaning of a conforming program.  Consider:
+
+                 struct Dense { static const unsigned int dim = 1; };
+
+                 template <template <typename> class View,
+                           typename Block>
+                 void operator+(float, View<Block> const&);
+
+                 template <typename Block, 
+                           unsigned int Dim = Block::dim>
+                 struct Lvalue_proxy { operator float() const; };
+
+                 void
+                 test_1d (void) {
+                   Lvalue_proxy<Dense> p;
+                   float b;
+                   b + p;
+                 }
 
-           if (coerce_template_parms (argtmplvec, parmvec, parmtmpl, 0, 1)
+             Here, if Lvalue_proxy is permitted to bind to View, then
+             the global operator+ will be used; if they are not, the
+             Lvalue_proxy will be converted to float.  */        
+           if (coerce_template_parms (argtmplvec, parmvec, 
+                                      TYPE_TI_TEMPLATE (parm),
+                                      tf_none,
+                                      /*require_all_args=*/true,
+                                      /*use_default_args=*/false)
                == error_mark_node)
              return 1;
 
@@ -10733,9 +10760,11 @@ get_bindings (tree fn, tree decl, tree explicit_args, bool check_rettype)
        return NULL_TREE;
 
       converted_args
-       = (coerce_template_parms (DECL_INNERMOST_TEMPLATE_PARMS (tmpl),
-                                 explicit_args, NULL_TREE,
-                                 tf_none, /*require_all_arguments=*/0));
+       = coerce_template_parms (DECL_INNERMOST_TEMPLATE_PARMS (tmpl),
+                                explicit_args, NULL_TREE,
+                                tf_none, 
+                                /*require_all_args=*/false,
+                                /*use_default_args=*/false);
       if (converted_args == error_mark_node)
        return NULL_TREE;
 
@@ -12215,7 +12244,13 @@ dependent_type_p (tree type)
   /* If there are no template parameters in scope, then there can't be
      any dependent types.  */
   if (!processing_template_decl)
-    return false;
+    {
+      /* If we are not processing a template, then nobody should be
+        providing us with a dependent type.  */
+      gcc_assert (type);
+      gcc_assert (TREE_CODE (type) != TEMPLATE_TYPE_PARM);
+      return false;
+    }
 
   /* If the type is NULL, we have not computed a type for the entity
      in question; in that case, the type is dependent.  */
index 3262a6ab82ef26602edfb7dac970fe2e8d9a7e45..dd2fdab292106c104fc54441a7c4fd98e24ce546 100644 (file)
@@ -1,3 +1,20 @@
+2006-02-07  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/9737
+       * g++.dg/template/ttp15.C: New test.
+       * g++.dg/template/ttp16.C: Likewise.
+       * g++.dg/template/ttp17.C: Likewise.
+       * g++.old-deja/g++.pt/ttp36.C: Remove.
+       * g++.old-deja/g++.pt/ttp19.C: Likewise.
+       * g++.old-deja/g++.pt/ttp37.C: Likewise.
+       * g++.old-deja/g++.pt/ttp38.C: Likewise.
+       * g++.old-deja/g++.pt/ttp39.C: Likewise.
+       * g++.old-deja/g++.pt/ttp9.C: Likewise.
+       * g++.old-deja/g++.pt/ttp40.C: Likewise.
+       * g++.old-deja/g++.pt/ttp51.C: Likewise.
+       * g++.old-deja/g++.pt/ttp26.C: Likewise.
+       * g++.old-deja/g++.pt/ttp36.C: Likewise.
+
 2005-02-06  Thomas Koenig  <Thomas.Koenig@online.de>
 
        PR libfortran/23815
diff --git a/gcc/testsuite/g++.dg/template/ttp15.C b/gcc/testsuite/g++.dg/template/ttp15.C
new file mode 100644 (file)
index 0000000..5bb285e
--- /dev/null
@@ -0,0 +1,21 @@
+struct Dense {
+  static const unsigned int dim = 1;
+};
+
+template <template <typename> class View,
+         typename Block>
+void operator+(float, View<Block> const&);
+
+template <typename Block,
+         unsigned int Dim = Block::dim>
+struct Lvalue_proxy {
+  operator float() const;
+};
+
+void
+test_1d (void)
+{
+  Lvalue_proxy<Dense> p;
+  float b;
+  b + p;
+}
diff --git a/gcc/testsuite/g++.dg/template/ttp16.C b/gcc/testsuite/g++.dg/template/ttp16.C
new file mode 100644 (file)
index 0000000..c556c7d
--- /dev/null
@@ -0,0 +1,7 @@
+template <template <typename> class C>
+void f() {}
+
+template <typename T, typename U = int>
+struct S {};
+
+template void f<S>(); // { dg-error "match" }
diff --git a/gcc/testsuite/g++.dg/template/ttp17.C b/gcc/testsuite/g++.dg/template/ttp17.C
new file mode 100644 (file)
index 0000000..f1ddeb1
--- /dev/null
@@ -0,0 +1,7 @@
+template <template <typename> class C>
+void f(C<double>) {}
+
+template <typename T, typename U = int>
+struct S {};
+
+template void f(S<double>); // { dg-error "match" }
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/ttp19.C b/gcc/testsuite/g++.old-deja/g++.pt/ttp19.C
deleted file mode 100644 (file)
index 76ff601..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-// { dg-do run  }
-#include <vector>
-
-template<template<class> class D,class E> class C
-{
-               D<E> d;
-       public:
-               int size() { return d.size(); }
-};
-
-template<template<class> class D,class E> int size(D<E> &d1)
-{
-       d1.size();
-       C<D,E> d2;
-       d2.size();
-       return 0;
-}
-
-int main()
-{
-       std::vector<int> c1;
-       std::vector<char> c2;
-       size(c1);
-       size(c2);
-}
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/ttp26.C b/gcc/testsuite/g++.old-deja/g++.pt/ttp26.C
deleted file mode 100644 (file)
index 0be2c44..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-// { dg-do run  }
-template<class T, class U = int> class D
-{
-       public:
-               int f();
-};
-
-template<class T, class U> int D<T,U>::f()
-{
-       return sizeof(T)+sizeof(U);
-}
-
-template<template<class> class D,class E> class C
-{
-               D<E> d;
-       public:
-               int f() { return d.f(); }
-};
-
-template<template<class> class D,class E> int f(D<E> &d1)
-{
-       d1.f();
-       C<D,E> d2;
-       d2.f();
-       return 0;
-}
-
-int main()
-{
-       D<int> c1;
-       D<char> c2;
-       f(c1);
-       f(c2);
-}
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/ttp35.C b/gcc/testsuite/g++.old-deja/g++.pt/ttp35.C
deleted file mode 100644 (file)
index 4e02a95..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-// { dg-do run  }
-template<int T, class U = int> class D
-{
-       public:
-               int f();
-};
-
-template<int T, class U> int D<T,U>::f()
-{
-       return T+sizeof(U);
-}
-
-template<template<int> class D,class E> class C
-{
-               D<1> d;
-       public:
-               int f() { return d.f(); }
-};
-
-template<template<int> class D> int f(D<2> &d1)
-{
-       d1.f();
-       return 0;
-}
-
-template<template<int> class D> int f(D<1> &d1)
-{
-       d1.f();
-       return 0;
-}
-
-int main()
-{
-       D<1> c1;
-       f(c1);
-}
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/ttp36.C b/gcc/testsuite/g++.old-deja/g++.pt/ttp36.C
deleted file mode 100644 (file)
index 2836e8a..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-// { dg-do run  }
-template<int T, class U = int> class D
-{
-       public:
-               int f();
-};
-
-template<int T, class U> int D<T,U>::f()
-{
-       return T+sizeof(U);
-}
-
-template<template<int> class D,class E> class C
-{
-               D<1> d;
-       public:
-               int f() { return d.f(); }
-};
-
-template<template<int> class D> int f(D<1> &d1)
-{
-       d1.f();
-       return 0;
-}
-
-int main()
-{
-       D<1> c1;
-       f(c1);
-}
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/ttp37.C b/gcc/testsuite/g++.old-deja/g++.pt/ttp37.C
deleted file mode 100644 (file)
index 4ef30dd..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-// { dg-do run  }
-template<int T, class U = int> class D
-{
-       public:
-               int f();
-};
-
-template<int T, class U> int D<T,U>::f()
-{
-       return T+sizeof(U);
-}
-
-template<template<int> class D,class E> class C
-{
-               D<1> d;
-       public:
-               int f() { return d.f(); }
-};
-
-template<template<int> class D, int T> int f(D<T> &d1)
-{
-       d1.f();
-       return T;
-}
-
-int main()
-{
-       D<1> c1;
-       f(c1);
-}
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/ttp38.C b/gcc/testsuite/g++.old-deja/g++.pt/ttp38.C
deleted file mode 100644 (file)
index be4bca9..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-// { dg-do run  }
-template<class T, class U = int> class D
-{
-       public:
-               int f();
-};
-
-template<class T, class U> int D<T,U>::f()
-{
-       return sizeof(T)+sizeof(U);
-}
-
-template<template<class> class D,class E> class C
-{
-               D<E> d;
-       public:
-               int f() { return d.f(); }
-};
-
-template<template<class> class D> int f(D<int> &d1)
-{
-       d1.f();
-       return 0;
-}
-
-int main()
-{
-       D<int> c1;
-       f(c1);
-}
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/ttp39.C b/gcc/testsuite/g++.old-deja/g++.pt/ttp39.C
deleted file mode 100644 (file)
index a962004..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-// { dg-do run  }
-template<class T, class U = T> class D
-{
-       public:
-               int f();
-};
-
-template<class T, class U> int D<T,U>::f()
-{
-       return sizeof(T)+sizeof(U);
-}
-
-template<template<class> class D,class E> class C
-{
-               D<E> d;
-       public:
-               int f() { return d.f(); }
-};
-
-template<template<class> class D> int f(D<int> &d1)
-{
-       d1.f();
-       return 0;
-}
-
-int main()
-{
-       D<int> c1;
-       f(c1);
-}
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/ttp40.C b/gcc/testsuite/g++.old-deja/g++.pt/ttp40.C
deleted file mode 100644 (file)
index 49d39e1..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-// { dg-do run  }
-#include <vector>
-
-template<class E,template<class> class DD = std::vector> class C
-{
-               DD<E> d;
-       public:
-               int f();
-};
-
-template<class E,template<class> class DD> int C<E,DD>::f()
-{
-       DD<E> d2;
-       return d2.size();
-}
-
-int main()
-{
-       C<int> c;
-       c.f();
-}
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/ttp51.C b/gcc/testsuite/g++.old-deja/g++.pt/ttp51.C
deleted file mode 100644 (file)
index db83349..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-// { dg-do run  }
-template<class E, int i, class F, class G=int, int j=i, class H=E> class D
-{
-};
-
-template<template<class,int,class,class> class D,class E> class C
-{
-       D<E,2,char,bool>        d;
-};
-
-int main()
-{
-       C<D,int> c;
-}
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/ttp9.C b/gcc/testsuite/g++.old-deja/g++.pt/ttp9.C
deleted file mode 100644 (file)
index 7ca9a9a..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-// { dg-do run  }
-template<class E,class F=int> class D
-{
-};
-
-template<template<class> class D,class E> class C
-{
-       D<E>    d;
-};
-
-int main()
-{
-       C<D,int> c;
-}
index dc35184762058a401ac301f4f66f6fed1cdcbbfc..520bbe2e4eb450aadb8e7609a645e1386916904e 100644 (file)
@@ -1,3 +1,9 @@
+2006-02-07  Mark Mitchell  <mark@codesourcery.com>
+
+       * testsuite/testsuite_tr1.h (test_property): New function.
+       * testsuite/tr1/4_metaprogramming/type_properties/extent/extent.cc 
+       (test01) 
+
 2006-02-05  Paolo Carlini  <pcarlini@suse.de>
 
        * include/tr1/cstdio: New.
index 7d5677f85ef67db24ec6e529146cb6e7c8d4c3f1..439d435ee8bf4f65e3d4e63d3c913fb40f71b05e 100644 (file)
@@ -64,6 +64,20 @@ namespace __gnu_test
       return ret;
     }
 
+  // For testing tr1/type_traits/extent, which has a second template
+  // parameter.
+  template<template<typename, unsigned> class Property,
+           typename Type,
+          unsigned Uint>
+    bool
+    test_property(typename Property<Type, Uint>::value_type value)
+    {
+      bool ret = true;
+      ret &= Property<Type, Uint>::value == value;
+      ret &= Property<Type, Uint>::type::value == value;
+      return ret;
+    }
+
   template<template<typename, typename> class Relationship,
            typename Type1, typename Type2>
     bool
index 39d067ef398f367774fc6d737d593a69a3e18cdf..6ccecacc06b83924c9e14346c3c74252a169389e 100644 (file)
@@ -30,19 +30,19 @@ void test01()
   using std::tr1::extent;
   using namespace __gnu_test;
 
-  VERIFY( (test_property<extent, int>(0)) );
-  VERIFY( (test_property<extent, int[2]>(2)) );
-  VERIFY( (test_property<extent, int[2][4]>(2)) );
-  VERIFY( (test_property<extent, int[][4]>(0)) );
+  VERIFY( (test_property<extent, int, 0>(0)) );
+  VERIFY( (test_property<extent, int[2], 0>(2)) );
+  VERIFY( (test_property<extent, int[2][4], 0>(2)) );
+  VERIFY( (test_property<extent, int[][4], 0>(0)) );
   VERIFY( (extent<int, 1>::value == 0) );
   VERIFY( (extent<int[2], 1>::value == 0) );
   VERIFY( (extent<int[2][4], 1>::value == 4) );
   VERIFY( (extent<int[][4], 1>::value == 4) );
   VERIFY( (extent<int[10][4][6][8][12][2], 4>::value == 12) );
-  VERIFY( (test_property<extent, ClassType>(0)) );
-  VERIFY( (test_property<extent, ClassType[2]>(2)) );
-  VERIFY( (test_property<extent, ClassType[2][4]>(2)) );
-  VERIFY( (test_property<extent, ClassType[][4]>(0)) );
+  VERIFY( (test_property<extent, ClassType, 0>(0)) );
+  VERIFY( (test_property<extent, ClassType[2], 0>(2)) );
+  VERIFY( (test_property<extent, ClassType[2][4], 0>(2)) );
+  VERIFY( (test_property<extent, ClassType[][4], 0>(0)) );
   VERIFY( (extent<ClassType, 1>::value == 0) );
   VERIFY( (extent<ClassType[2], 1>::value == 0) );
   VERIFY( (extent<ClassType[2][4], 1>::value == 4) );