re PR c++/9737 ([DR150] Partial template specialisation selection failure involving template parameter defaults)
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
This commit is contained in:
parent
3696813180
commit
e7e9396544
19 changed files with 167 additions and 310 deletions
|
@ -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.
|
||||
|
|
111
gcc/cp/pt.c
111
gcc/cp/pt.c
|
@ -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:
|
||||
|
||||
if (coerce_template_parms (argtmplvec, parmvec, parmtmpl, 0, 1)
|
||||
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;
|
||||
}
|
||||
|
||||
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. */
|
||||
|
|
|
@ -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
|
||||
|
|
21
gcc/testsuite/g++.dg/template/ttp15.C
Normal file
21
gcc/testsuite/g++.dg/template/ttp15.C
Normal file
|
@ -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;
|
||||
}
|
7
gcc/testsuite/g++.dg/template/ttp16.C
Normal file
7
gcc/testsuite/g++.dg/template/ttp16.C
Normal file
|
@ -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" }
|
7
gcc/testsuite/g++.dg/template/ttp17.C
Normal file
7
gcc/testsuite/g++.dg/template/ttp17.C
Normal file
|
@ -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" }
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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();
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) );
|
||||
|
|
Loading…
Add table
Reference in a new issue