re PR c++/26099 (support for type traits is not available)

gcc/
2007-03-30  Paolo Carlini  <pcarlini@suse.de>

	PR c++/26099
	* c-common.h (enum rid): Add RID_HAS_NOTHROW_ASSIGN,
	RID_HAS_NOTHROW_CONSTRUCTOR, RID_HAS_NOTHROW_COPY,
	RID_HAS_TRIVIAL_ASSIGN, RID_HAS_TRIVIAL_CONSTRUCTOR,
	RID_HAS_TRIVIAL_COPY, RID_HAS_TRIVIAL_DESTRUCTOR,
	RID_HAS_VIRTUAL_DESTRUCTOR, RID_IS_ABSTRACT, RID_IS_BASE_OF,
	RID_IS_CONVERTIBLE_TO, RID_IS_CLASS, RID_IS_EMPTY, RID_IS_ENUM,
	RID_IS_POD, RID_IS_POLYMORPHIC, RID_IS_UNION, as
	C++ extensions.
	* doc/extend.texi (Extensions to the C++ Language): Add Type Traits.

gcc/cp/
2007-03-30  Paolo Carlini  <pcarlini@suse.de>

	PR c++/26099
	* cp-tree.h (enum cp_trait_kind, struct tree_trait_expr,
	TRAIT_EXPR_TYPE1, TRAIT_EXPR_TYPE2, TRAIT_EXPR_KIND): Add.
	(enum cp_tree_node_structure_enum, union lang_tree_node): Update.
	(CLASS_TYPE_NON_UNION_P): Add.
	(struct lang_type_class): Add has_complex_dflt.
	(TYPE_HAS_COMPLEX_DFLT, TYPE_HAS_TRIVIAL_DFLT): Add.
	(locate_copy, locate_ctor, locate_dtor, finish_trait_expr): Declare.
	* cp-tree.def: Add TRAIT_EXPR.
	* cp-objcp-common.c (cp_tree_size): Add TRAIT_EXPR case.
	* lex.c (struct resword): Add __has_nothrow_assign,
	__has_nothrow_constructor, __has_nothrow_copy, __has_trivial_assign,
	__has_trivial_constructor, __has_trivial_copy,
	__has_trivial_destructor, __has_virtual_destructor, __is_abstract,
	__is_base_of, __is_class, __is_convertible_to, __is_empty, __is_enum,
	__is_pod, __is_polymorphic, __is_union.
	* parser.c (cp_parser_primary_expression): Deal with the new RIDs.
	(cp_parser_trait_expr): New.
	* semantics.c (finish_trait_expr, trait_expr_value
	classtype_has_nothrow_copy_or_assign_p): New.
	* method.c (locate_copy, locate_ctor, locate_dtor): Do not define
	as static.
	* decl.c (cp_tree_node_structure): Add TRAIT_EXPR.
	* class.c (check_bases, check_field_decl, check_bases_and_members):
	Deal with TYPE_HAS_COMPLEX_DFLT (t) too.
	* pt.c (uses_template_parms, tsubst_copy_and_build,
	value_dependent_expression_p, type_dependent_expression_p): Deal with
	TRAIT_EXPR.
	* tree.c (cp_walk_subtrees): Deal with TRAIT_EXPR.

gcc/testsuite/
2007-03-30  Paolo Carlini  <pcarlini@suse.de>

	PR c++/26099
	* g++.dg/ext/is_base_of.C: New.
	* g++.dg/ext/has_virtual_destructor.C: New.
	* g++.dg/ext/is_polymorphic.C: New.
	* g++.dg/ext/is_base_of_diagnostic.C: New.
	* g++.dg/ext/is_enum.C: New.
	* g++.dg/ext/has_nothrow_assign.C: New.
	* g++.dg/ext/has_nothrow_constructor.C: New.
	* g++.dg/ext/is_empty.C: New.
	* g++.dg/ext/has_trivial_copy.C: New.
	* g++.dg/ext/has_trivial_assign.C: New.
	* g++.dg/ext/is_abstract.C: New.
	* g++.dg/ext/is_pod.C: New.
	* g++.dg/ext/has_nothrow_copy.C: New.
	* g++.dg/ext/is_class.C: New.
	* g++.dg/ext/has_trivial_constructor.C: New.
	* g++.dg/ext/is_union.C: New.
	* g++.dg/ext/has_trivial_destructor.C: New.
	* g++.dg/tree-ssa/pr22444.C: Adjust, avoid __is_pod.
	* g++.dg/template/crash43.C: Likewise.

libstdc++-v3/
2007-03-30  Paolo Carlini  <pcarlini@suse.de>

	PR c++/26099
	* include/bits/cpp_type_traits.h (struct __is_pod, struct __is_empty):
	Remove.
	* include/bits/valarray_array.h: Adjust.
	* include/bits/allocator.h: Likewise.
	* include/bits/stl_tree.h: Likewise.

From-SVN: r123366
This commit is contained in:
Paolo Carlini 2007-03-30 19:45:57 +00:00 committed by Paolo Carlini
parent c7a0240aa5
commit cb68ec5005
40 changed files with 2240 additions and 68 deletions

View File

@ -1,3 +1,16 @@
2007-03-30 Paolo Carlini <pcarlini@suse.de>
PR c++/26099
* c-common.h (enum rid): Add RID_HAS_NOTHROW_ASSIGN,
RID_HAS_NOTHROW_CONSTRUCTOR, RID_HAS_NOTHROW_COPY,
RID_HAS_TRIVIAL_ASSIGN, RID_HAS_TRIVIAL_CONSTRUCTOR,
RID_HAS_TRIVIAL_COPY, RID_HAS_TRIVIAL_DESTRUCTOR,
RID_HAS_VIRTUAL_DESTRUCTOR, RID_IS_ABSTRACT, RID_IS_BASE_OF,
RID_IS_CONVERTIBLE_TO, RID_IS_CLASS, RID_IS_EMPTY, RID_IS_ENUM,
RID_IS_POD, RID_IS_POLYMORPHIC, RID_IS_UNION, as
C++ extensions.
* doc/extend.texi (Extensions to the C++ Language): Add Type Traits.
2007-03-30 Steven Bosscher <steven@gcc.gnu.org>
* regmove.c: Move all of pass_stack_adjustments from here...

View File

@ -90,6 +90,17 @@ enum rid
/* casts */
RID_CONSTCAST, RID_DYNCAST, RID_REINTCAST, RID_STATCAST,
/* C++ extensions */
RID_HAS_NOTHROW_ASSIGN, RID_HAS_NOTHROW_CONSTRUCTOR,
RID_HAS_NOTHROW_COPY, RID_HAS_TRIVIAL_ASSIGN,
RID_HAS_TRIVIAL_CONSTRUCTOR, RID_HAS_TRIVIAL_COPY,
RID_HAS_TRIVIAL_DESTRUCTOR, RID_HAS_VIRTUAL_DESTRUCTOR,
RID_IS_ABSTRACT, RID_IS_BASE_OF,
RID_IS_CONVERTIBLE_TO, RID_IS_CLASS,
RID_IS_EMPTY, RID_IS_ENUM,
RID_IS_POD, RID_IS_POLYMORPHIC,
RID_IS_UNION,
/* C++0x */
RID_STATIC_ASSERT,

View File

@ -1,3 +1,35 @@
2007-03-30 Paolo Carlini <pcarlini@suse.de>
PR c++/26099
* cp-tree.h (enum cp_trait_kind, struct tree_trait_expr,
TRAIT_EXPR_TYPE1, TRAIT_EXPR_TYPE2, TRAIT_EXPR_KIND): Add.
(enum cp_tree_node_structure_enum, union lang_tree_node): Update.
(CLASS_TYPE_NON_UNION_P): Add.
(struct lang_type_class): Add has_complex_dflt.
(TYPE_HAS_COMPLEX_DFLT, TYPE_HAS_TRIVIAL_DFLT): Add.
(locate_copy, locate_ctor, locate_dtor, finish_trait_expr): Declare.
* cp-tree.def: Add TRAIT_EXPR.
* cp-objcp-common.c (cp_tree_size): Add TRAIT_EXPR case.
* lex.c (struct resword): Add __has_nothrow_assign,
__has_nothrow_constructor, __has_nothrow_copy, __has_trivial_assign,
__has_trivial_constructor, __has_trivial_copy,
__has_trivial_destructor, __has_virtual_destructor, __is_abstract,
__is_base_of, __is_class, __is_convertible_to, __is_empty, __is_enum,
__is_pod, __is_polymorphic, __is_union.
* parser.c (cp_parser_primary_expression): Deal with the new RIDs.
(cp_parser_trait_expr): New.
* semantics.c (finish_trait_expr, trait_expr_value
classtype_has_nothrow_copy_or_assign_p): New.
* method.c (locate_copy, locate_ctor, locate_dtor): Do not define
as static.
* decl.c (cp_tree_node_structure): Add TRAIT_EXPR.
* class.c (check_bases, check_field_decl, check_bases_and_members):
Deal with TYPE_HAS_COMPLEX_DFLT (t) too.
* pt.c (uses_template_parms, tsubst_copy_and_build,
value_dependent_expression_p, type_dependent_expression_p): Deal with
TRAIT_EXPR.
* tree.c (cp_walk_subtrees): Deal with TRAIT_EXPR.
2007-03-29 Richard Guenther <rguenther@suse.de>
* tree.c (cp_walk_subtrees): Do not set input_location.

View File

@ -1270,6 +1270,7 @@ check_bases (tree t,
TYPE_POLYMORPHIC_P (t) |= TYPE_POLYMORPHIC_P (basetype);
CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t)
|= CLASSTYPE_CONTAINS_EMPTY_CLASS_P (basetype);
TYPE_HAS_COMPLEX_DFLT (t) |= TYPE_HAS_COMPLEX_DFLT (basetype);
}
}
@ -2753,6 +2754,7 @@ check_field_decl (tree field,
|= TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type);
TYPE_HAS_COMPLEX_ASSIGN_REF (t) |= TYPE_HAS_COMPLEX_ASSIGN_REF (type);
TYPE_HAS_COMPLEX_INIT_REF (t) |= TYPE_HAS_COMPLEX_INIT_REF (type);
TYPE_HAS_COMPLEX_DFLT (t) |= TYPE_HAS_COMPLEX_DFLT (type);
}
if (!TYPE_HAS_CONST_INIT_REF (type))
@ -4113,6 +4115,8 @@ check_bases_and_members (tree t)
|| TYPE_HAS_ASSIGN_REF (t));
TYPE_HAS_COMPLEX_ASSIGN_REF (t)
|= TYPE_HAS_ASSIGN_REF (t) || TYPE_CONTAINS_VPTR_P (t);
TYPE_HAS_COMPLEX_DFLT (t)
|= (TYPE_HAS_DEFAULT_CONSTRUCTOR (t) || TYPE_CONTAINS_VPTR_P (t));
/* Synthesize any needed methods. */
add_implicitly_declared_members (t,

View File

@ -135,6 +135,9 @@ cp_tree_size (enum tree_code code)
case ARGUMENT_PACK_SELECT:
return sizeof (struct tree_argument_pack_select);
case TRAIT_EXPR:
return sizeof (struct tree_trait_expr);
default:
gcc_unreachable ();
}

View File

@ -422,6 +422,11 @@ DEFTREECODE (EXPR_PACK_EXPANSION, "expr_pack_expansion", tcc_expression, 1)
index is a machine integer. */
DEFTREECODE (ARGUMENT_PACK_SELECT, "argument_pack_select", tcc_exceptional, 0)
/** C++ extensions. */
/* Represents a trait expression during template expansion. */
DEFTREECODE (TRAIT_EXPR, "trait_expr", tcc_exceptional, 0)
/*
Local variables:
mode:c

View File

@ -478,6 +478,48 @@ struct tree_argument_pack_select GTY (())
int index;
};
/* The different kinds of traits that we encounter. */
typedef enum cp_trait_kind
{
CPTK_HAS_NOTHROW_ASSIGN,
CPTK_HAS_NOTHROW_CONSTRUCTOR,
CPTK_HAS_NOTHROW_COPY,
CPTK_HAS_TRIVIAL_ASSIGN,
CPTK_HAS_TRIVIAL_CONSTRUCTOR,
CPTK_HAS_TRIVIAL_COPY,
CPTK_HAS_TRIVIAL_DESTRUCTOR,
CPTK_HAS_VIRTUAL_DESTRUCTOR,
CPTK_IS_ABSTRACT,
CPTK_IS_BASE_OF,
CPTK_IS_CLASS,
CPTK_IS_CONVERTIBLE_TO,
CPTK_IS_EMPTY,
CPTK_IS_ENUM,
CPTK_IS_POD,
CPTK_IS_POLYMORPHIC,
CPTK_IS_UNION
} cp_trait_kind;
/* The types that we are processing. */
#define TRAIT_EXPR_TYPE1(NODE) \
(((struct tree_trait_expr *)TRAIT_EXPR_CHECK (NODE))->type1)
#define TRAIT_EXPR_TYPE2(NODE) \
(((struct tree_trait_expr *)TRAIT_EXPR_CHECK (NODE))->type2)
/* The specific trait that we are processing. */
#define TRAIT_EXPR_KIND(NODE) \
(((struct tree_trait_expr *)TRAIT_EXPR_CHECK (NODE))->kind)
struct tree_trait_expr GTY (())
{
struct tree_common common;
tree type1;
tree type2;
enum cp_trait_kind kind;
};
enum cp_tree_node_structure_enum {
TS_CP_GENERIC,
TS_CP_IDENTIFIER,
@ -491,6 +533,7 @@ enum cp_tree_node_structure_enum {
TS_CP_DEFAULT_ARG,
TS_CP_STATIC_ASSERT,
TS_CP_ARGUMENT_PACK_SELECT,
TS_CP_TRAIT_EXPR,
LAST_TS_CP_ENUM
};
@ -511,6 +554,8 @@ union lang_tree_node GTY((desc ("cp_tree_node_structure (&%h)"),
static_assertion;
struct tree_argument_pack_select GTY ((tag ("TS_CP_ARGUMENT_PACK_SELECT")))
argument_pack_select;
struct tree_trait_expr GTY ((tag ("TS_CP_TRAIT_EXPR")))
trait_expression;
};
@ -936,6 +981,10 @@ enum languages { lang_c, lang_cplusplus, lang_java };
#define CLASS_TYPE_P(T) \
(IS_AGGR_TYPE_CODE (TREE_CODE (T)) && TYPE_LANG_FLAG_5 (T))
/* Nonzero if T is a class type but not an union. */
#define NON_UNION_CLASS_TYPE_P(T) \
(CLASS_TYPE_P (T) && TREE_CODE (T) != UNION_TYPE)
/* Keep these checks in ascending code order. */
#define IS_AGGR_TYPE_CODE(T) \
((T) == RECORD_TYPE || (T) == UNION_TYPE)
@ -1093,6 +1142,7 @@ struct lang_type_class GTY(())
unsigned has_complex_init_ref : 1;
unsigned has_complex_assign_ref : 1;
unsigned non_aggregate : 1;
unsigned has_complex_dflt : 1;
/* When adding a flag here, consider whether or not it ought to
apply to a template instance if it applies to the template. If
@ -1101,7 +1151,7 @@ struct lang_type_class GTY(())
/* There are some bits left to fill out a 32-bit word. Keep track
of this by updating the size of this bitfield whenever you add or
remove a flag. */
unsigned dummy : 12;
unsigned dummy : 11;
tree primary_base;
VEC(tree_pair_s,gc) *vcall_indices;
@ -2682,8 +2732,13 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
/* Nonzero if there is a user-defined X::op=(x&) for this class. */
#define TYPE_HAS_COMPLEX_ASSIGN_REF(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_complex_assign_ref)
/* Nonzero if there is a user-defined X::X(x&) for this class. */
#define TYPE_HAS_COMPLEX_INIT_REF(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_complex_init_ref)
/* Nonzero if there is a user-defined default constructor for this class. */
#define TYPE_HAS_COMPLEX_DFLT(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_complex_dflt)
/* Nonzero if TYPE has a trivial destructor. From [class.dtor]:
A destructor is trivial if it is an implicitly declared
@ -2705,6 +2760,10 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
#define TYPE_HAS_NONTRIVIAL_DESTRUCTOR(NODE) \
(TYPE_LANG_FLAG_4 (NODE))
/* Nonzero for class type means that the default constructor is trivial. */
#define TYPE_HAS_TRIVIAL_DFLT(NODE) \
(TYPE_HAS_DEFAULT_CONSTRUCTOR (NODE) && ! TYPE_HAS_COMPLEX_DFLT (NODE))
/* Nonzero for class type means that copy initialization of this type can use
a bitwise copy. */
#define TYPE_HAS_TRIVIAL_INIT_REF(NODE) \
@ -4280,6 +4339,9 @@ extern tree lazily_declare_fn (special_function_kind,
extern tree skip_artificial_parms_for (tree, tree);
extern int num_artificial_parms_for (tree);
extern tree make_alias_for (tree, tree);
extern tree locate_copy (tree, void *);
extern tree locate_ctor (tree, void *);
extern tree locate_dtor (tree, void *);
/* In optimize.c */
extern bool maybe_clone_body (tree);
@ -4557,6 +4619,7 @@ extern bool cxx_omp_privatize_by_reference (tree);
extern tree baselink_for_fns (tree);
extern void finish_static_assert (tree, tree, location_t,
bool);
extern tree finish_trait_expr (enum cp_trait_kind, tree, tree);
/* in tree.c */
extern void lang_check_failed (const char *, int,

View File

@ -11739,6 +11739,7 @@ cp_tree_node_structure (union lang_tree_node * t)
case BASELINK: return TS_CP_BASELINK;
case STATIC_ASSERT: return TS_CP_STATIC_ASSERT;
case ARGUMENT_PACK_SELECT: return TS_CP_ARGUMENT_PACK_SELECT;
case TRAIT_EXPR: return TS_CP_TRAIT_EXPR;
default: return TS_CP_GENERIC;
}
}

View File

@ -199,6 +199,23 @@ static const struct resword reswords[] =
{ "__const__", RID_CONST, 0 },
{ "__extension__", RID_EXTENSION, 0 },
{ "__func__", RID_C99_FUNCTION_NAME, 0 },
{ "__has_nothrow_assign", RID_HAS_NOTHROW_ASSIGN, 0 },
{ "__has_nothrow_constructor", RID_HAS_NOTHROW_CONSTRUCTOR, 0 },
{ "__has_nothrow_copy", RID_HAS_NOTHROW_COPY, 0 },
{ "__has_trivial_assign", RID_HAS_TRIVIAL_ASSIGN, 0 },
{ "__has_trivial_constructor", RID_HAS_TRIVIAL_CONSTRUCTOR, 0 },
{ "__has_trivial_copy", RID_HAS_TRIVIAL_COPY, 0 },
{ "__has_trivial_destructor", RID_HAS_TRIVIAL_DESTRUCTOR, 0 },
{ "__has_virtual_destructor", RID_HAS_VIRTUAL_DESTRUCTOR, 0 },
{ "__is_abstract", RID_IS_ABSTRACT, 0 },
{ "__is_base_of", RID_IS_BASE_OF, 0 },
{ "__is_class", RID_IS_CLASS, 0 },
{ "__is_convertible_to", RID_IS_CONVERTIBLE_TO, 0 },
{ "__is_empty", RID_IS_EMPTY, 0 },
{ "__is_enum", RID_IS_ENUM, 0 },
{ "__is_pod", RID_IS_POD, 0 },
{ "__is_polymorphic", RID_IS_POLYMORPHIC, 0 },
{ "__is_union", RID_IS_UNION, 0 },
{ "__imag", RID_IMAGPART, 0 },
{ "__imag__", RID_IMAGPART, 0 },
{ "__inline", RID_INLINE, 0 },

View File

@ -61,9 +61,6 @@ static tree thunk_adjust (tree, bool, HOST_WIDE_INT, tree);
static void do_build_assign_ref (tree);
static void do_build_copy_constructor (tree);
static tree synthesize_exception_spec (tree, tree (*) (tree, void *), void *);
static tree locate_dtor (tree, void *);
static tree locate_ctor (tree, void *);
static tree locate_copy (tree, void *);
static tree make_alias_for_thunk (tree);
/* Called once to initialize method.c. */
@ -868,7 +865,7 @@ synthesize_exception_spec (tree type, tree (*extractor) (tree, void*),
/* Locate the dtor of TYPE. */
static tree
tree
locate_dtor (tree type, void *client ATTRIBUTE_UNUSED)
{
return CLASSTYPE_DESTRUCTORS (type);
@ -876,7 +873,7 @@ locate_dtor (tree type, void *client ATTRIBUTE_UNUSED)
/* Locate the default ctor of TYPE. */
static tree
tree
locate_ctor (tree type, void *client ATTRIBUTE_UNUSED)
{
tree fns;
@ -912,7 +909,7 @@ struct copy_data
points to a COPY_DATA holding the name (NULL for the ctor)
and desired qualifiers of the source operand. */
static tree
tree
locate_copy (tree type, void *client_)
{
struct copy_data *client = (struct copy_data *)client_;

View File

@ -1897,6 +1897,8 @@ static void cp_parser_late_parsing_default_args
(cp_parser *, tree);
static tree cp_parser_sizeof_operand
(cp_parser *, enum rid);
static tree cp_parser_trait_expr
(cp_parser *, enum rid);
static bool cp_parser_declares_only_class_p
(cp_parser *);
static void cp_parser_set_storage_class
@ -2959,6 +2961,25 @@ cp_parser_translation_unit (cp_parser* parser)
__builtin_va_arg ( assignment-expression , type-id )
__builtin_offsetof ( type-id , offsetof-expression )
C++ Extensions:
__has_nothrow_assign ( type-id )
__has_nothrow_constructor ( type-id )
__has_nothrow_copy ( type-id )
__has_trivial_assign ( type-id )
__has_trivial_constructor ( type-id )
__has_trivial_copy ( type-id )
__has_trivial_destructor ( type-id )
__has_virtual_destructor ( type-id )
__is_abstract ( type-id )
__is_base_of ( type-id , type-id )
__is_class ( type-id )
__is_convertible_to ( type-id , type-id )
__is_empty ( type-id )
__is_enum ( type-id )
__is_pod ( type-id )
__is_polymorphic ( type-id )
__is_union ( type-id )
Objective-C++ Extension:
primary-expression:
@ -3201,7 +3222,26 @@ cp_parser_primary_expression (cp_parser *parser,
case RID_OFFSETOF:
return cp_parser_builtin_offsetof (parser);
/* Objective-C++ expressions. */
case RID_HAS_NOTHROW_ASSIGN:
case RID_HAS_NOTHROW_CONSTRUCTOR:
case RID_HAS_NOTHROW_COPY:
case RID_HAS_TRIVIAL_ASSIGN:
case RID_HAS_TRIVIAL_CONSTRUCTOR:
case RID_HAS_TRIVIAL_COPY:
case RID_HAS_TRIVIAL_DESTRUCTOR:
case RID_HAS_VIRTUAL_DESTRUCTOR:
case RID_IS_ABSTRACT:
case RID_IS_BASE_OF:
case RID_IS_CLASS:
case RID_IS_CONVERTIBLE_TO:
case RID_IS_EMPTY:
case RID_IS_ENUM:
case RID_IS_POD:
case RID_IS_POLYMORPHIC:
case RID_IS_UNION:
return cp_parser_trait_expr (parser, token->keyword);
/* Objective-C++ expressions. */
case RID_AT_ENCODE:
case RID_AT_PROTOCOL:
case RID_AT_SELECTOR:
@ -6309,6 +6349,112 @@ cp_parser_builtin_offsetof (cp_parser *parser)
return expr;
}
/* Parse a trait expression. */
static tree
cp_parser_trait_expr (cp_parser* parser, enum rid keyword)
{
cp_trait_kind kind;
tree type1, type2 = NULL_TREE;
bool binary = false;
cp_decl_specifier_seq decl_specs;
switch (keyword)
{
case RID_HAS_NOTHROW_ASSIGN:
kind = CPTK_HAS_NOTHROW_ASSIGN;
break;
case RID_HAS_NOTHROW_CONSTRUCTOR:
kind = CPTK_HAS_NOTHROW_CONSTRUCTOR;
break;
case RID_HAS_NOTHROW_COPY:
kind = CPTK_HAS_NOTHROW_COPY;
break;
case RID_HAS_TRIVIAL_ASSIGN:
kind = CPTK_HAS_TRIVIAL_ASSIGN;
break;
case RID_HAS_TRIVIAL_CONSTRUCTOR:
kind = CPTK_HAS_TRIVIAL_CONSTRUCTOR;
break;
case RID_HAS_TRIVIAL_COPY:
kind = CPTK_HAS_TRIVIAL_COPY;
break;
case RID_HAS_TRIVIAL_DESTRUCTOR:
kind = CPTK_HAS_TRIVIAL_DESTRUCTOR;
break;
case RID_HAS_VIRTUAL_DESTRUCTOR:
kind = CPTK_HAS_VIRTUAL_DESTRUCTOR;
break;
case RID_IS_ABSTRACT:
kind = CPTK_IS_ABSTRACT;
break;
case RID_IS_BASE_OF:
kind = CPTK_IS_BASE_OF;
binary = true;
break;
case RID_IS_CLASS:
kind = CPTK_IS_CLASS;
break;
case RID_IS_CONVERTIBLE_TO:
kind = CPTK_IS_CONVERTIBLE_TO;
binary = true;
break;
case RID_IS_EMPTY:
kind = CPTK_IS_EMPTY;
break;
case RID_IS_ENUM:
kind = CPTK_IS_ENUM;
break;
case RID_IS_POD:
kind = CPTK_IS_POD;
break;
case RID_IS_POLYMORPHIC:
kind = CPTK_IS_POLYMORPHIC;
break;
case RID_IS_UNION:
kind = CPTK_IS_UNION;
break;
default:
gcc_unreachable ();
}
/* Consume the token. */
cp_lexer_consume_token (parser->lexer);
cp_parser_require (parser, CPP_OPEN_PAREN, "`('");
type1 = cp_parser_type_id (parser);
/* Build a trivial decl-specifier-seq. */
clear_decl_specs (&decl_specs);
decl_specs.type = type1;
/* Call grokdeclarator to figure out what type this is. */
type1 = grokdeclarator (NULL, &decl_specs, TYPENAME,
/*initialized=*/0, /*attrlist=*/NULL);
if (binary)
{
cp_parser_require (parser, CPP_COMMA, "`,'");
type2 = cp_parser_type_id (parser);
/* Build a trivial decl-specifier-seq. */
clear_decl_specs (&decl_specs);
decl_specs.type = type2;
/* Call grokdeclarator to figure out what type this is. */
type2 = grokdeclarator (NULL, &decl_specs, TYPENAME,
/*initialized=*/0, /*attrlist=*/NULL);
}
cp_parser_require (parser, CPP_CLOSE_PAREN, "`)'");
/* Complete the trait expr, which may mean either processing the
static assert now or saving it for template instantiation. */
return finish_trait_expr (kind, type1, type2);
}
/* Statements [gram.stmt.stmt] */
/* Parse a statement.

View File

@ -5818,6 +5818,7 @@ uses_template_parms (tree t)
|| TREE_CODE (t) == OVERLOAD
|| TREE_CODE (t) == BASELINK
|| TREE_CODE (t) == IDENTIFIER_NODE
|| TREE_CODE (t) == TRAIT_EXPR
|| CONSTANT_CLASS_P (t))
dependent_p = (type_dependent_expression_p (t)
|| value_dependent_expression_p (t));
@ -10703,6 +10704,18 @@ tsubst_copy_and_build (tree t,
case OFFSETOF_EXPR:
return finish_offsetof (RECUR (TREE_OPERAND (t, 0)));
case TRAIT_EXPR:
{
tree type1 = tsubst_copy (TRAIT_EXPR_TYPE1 (t), args,
complain, in_decl);
tree type2 = TRAIT_EXPR_TYPE2 (t);
if (type2)
type2 = tsubst_copy (type2, args, complain, in_decl);
return finish_trait_expr (TRAIT_EXPR_KIND (t), type1, type2);
}
case STMT_EXPR:
{
tree old_stmt_expr = cur_stmt_expr;
@ -14912,6 +14925,13 @@ value_dependent_expression_p (tree expression)
return false;
}
case TRAIT_EXPR:
{
tree type2 = TRAIT_EXPR_TYPE2 (expression);
return (dependent_type_p (TRAIT_EXPR_TYPE1 (expression))
|| (type2 ? dependent_type_p (type2) : false));
}
default:
/* A constant expression is value-dependent if any subexpression is
value-dependent. */
@ -14975,6 +14995,7 @@ type_dependent_expression_p (tree expression)
if (TREE_CODE (expression) == PSEUDO_DTOR_EXPR
|| TREE_CODE (expression) == SIZEOF_EXPR
|| TREE_CODE (expression) == ALIGNOF_EXPR
|| TREE_CODE (expression) == TRAIT_EXPR
|| TREE_CODE (expression) == TYPEID_EXPR
|| TREE_CODE (expression) == DELETE_EXPR
|| TREE_CODE (expression) == VEC_DELETE_EXPR

View File

@ -4007,4 +4007,210 @@ finish_static_assert (tree condition, tree message, location_t location,
}
}
/* Called from trait_expr_value to evaluate either __has_nothrow_copy or
__has_nothrow_assign, depending on copy_p. */
static bool
classtype_has_nothrow_copy_or_assign_p (tree type, bool copy_p)
{
if ((copy_p && TYPE_HAS_INIT_REF (type))
|| (!copy_p && TYPE_HAS_ASSIGN_REF (type)))
{
bool const_p = false;
tree t;
struct copy_data
{
tree name;
int quals;
} data;
data.name = copy_p ? NULL_TREE : ansi_assopname (NOP_EXPR);
data.quals = TYPE_QUAL_CONST;
t = locate_copy (type, &data);
if (t)
{
const_p = true;
if (!TREE_NOTHROW (t))
return false;
}
if (copy_p || !CP_TYPE_CONST_P (type))
{
data.quals = TYPE_UNQUALIFIED;
t = locate_copy (type, &data);
if (t && !TREE_NOTHROW (t))
return false;
data.quals = TYPE_QUAL_VOLATILE;
t = locate_copy (type, &data);
if (t && !TREE_NOTHROW (t))
return false;
}
data.quals = (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
t = locate_copy (type, &data);
if (t)
{
const_p = true;
if (!TREE_NOTHROW (t))
return false;
}
if (!copy_p && CP_TYPE_CONST_P (type) && !const_p)
return false;
}
else
return false;
return true;
}
/* Actually evaluates the trait. */
static bool
trait_expr_value (cp_trait_kind kind, tree type1, tree type2)
{
enum tree_code type_code1;
tree t;
type_code1 = TREE_CODE (type1);
switch (kind)
{
case CPTK_HAS_NOTHROW_ASSIGN:
return (trait_expr_value (CPTK_HAS_TRIVIAL_ASSIGN, type1, type2)
|| (CLASS_TYPE_P (type1)
&& classtype_has_nothrow_copy_or_assign_p (type1, false)));
case CPTK_HAS_TRIVIAL_ASSIGN:
return (!CP_TYPE_CONST_P (type1) && type_code1 != REFERENCE_TYPE
&& (pod_type_p (type1)
|| (CLASS_TYPE_P (type1)
&& TYPE_HAS_TRIVIAL_ASSIGN_REF (type1))));
case CPTK_HAS_NOTHROW_CONSTRUCTOR:
type1 = strip_array_types (type1);
return (trait_expr_value (CPTK_HAS_TRIVIAL_CONSTRUCTOR, type1, type2)
|| (CLASS_TYPE_P (type1)
&& (t = locate_ctor (type1, NULL)) && TREE_NOTHROW (t)));
case CPTK_HAS_TRIVIAL_CONSTRUCTOR:
type1 = strip_array_types (type1);
return (pod_type_p (type1)
|| (CLASS_TYPE_P (type1) && TYPE_HAS_TRIVIAL_DFLT (type1)));
case CPTK_HAS_NOTHROW_COPY:
return (trait_expr_value (CPTK_HAS_TRIVIAL_COPY, type1, type2)
|| (CLASS_TYPE_P (type1)
&& classtype_has_nothrow_copy_or_assign_p (type1, true)));
case CPTK_HAS_TRIVIAL_COPY:
return (pod_type_p (type1) || type_code1 == REFERENCE_TYPE
|| (CLASS_TYPE_P (type1) && TYPE_HAS_TRIVIAL_INIT_REF (type1)));
case CPTK_HAS_TRIVIAL_DESTRUCTOR:
type1 = strip_array_types (type1);
return (pod_type_p (type1)
|| (CLASS_TYPE_P (type1)
&& TYPE_HAS_TRIVIAL_DESTRUCTOR (type1)));
case CPTK_HAS_VIRTUAL_DESTRUCTOR:
return (CLASS_TYPE_P (type1)
&& (t = locate_dtor (type1, NULL)) && DECL_VIRTUAL_P (t));
case CPTK_IS_ABSTRACT:
return (CLASS_TYPE_P (type1) && CLASSTYPE_PURE_VIRTUALS (type1));
case CPTK_IS_BASE_OF:
return (NON_UNION_CLASS_TYPE_P (type1) && NON_UNION_CLASS_TYPE_P (type2)
&& DERIVED_FROM_P (type1, type2));
case CPTK_IS_CLASS:
return (NON_UNION_CLASS_TYPE_P (type1));
case CPTK_IS_CONVERTIBLE_TO:
/* TODO */
return false;
case CPTK_IS_EMPTY:
return (NON_UNION_CLASS_TYPE_P (type1) && CLASSTYPE_EMPTY_P (type1));
case CPTK_IS_ENUM:
return (type_code1 == ENUMERAL_TYPE);
case CPTK_IS_POD:
return (pod_type_p (type1));
case CPTK_IS_POLYMORPHIC:
return (CLASS_TYPE_P (type1) && TYPE_POLYMORPHIC_P (type1));
case CPTK_IS_UNION:
return (type_code1 == UNION_TYPE);
default:
gcc_unreachable ();
return false;
}
}
/* Process a trait expression. */
tree
finish_trait_expr (cp_trait_kind kind, tree type1, tree type2)
{
gcc_assert (kind == CPTK_HAS_NOTHROW_ASSIGN
|| kind == CPTK_HAS_NOTHROW_CONSTRUCTOR
|| kind == CPTK_HAS_NOTHROW_COPY
|| kind == CPTK_HAS_TRIVIAL_ASSIGN
|| kind == CPTK_HAS_TRIVIAL_CONSTRUCTOR
|| kind == CPTK_HAS_TRIVIAL_COPY
|| kind == CPTK_HAS_TRIVIAL_DESTRUCTOR
|| kind == CPTK_HAS_VIRTUAL_DESTRUCTOR
|| kind == CPTK_IS_ABSTRACT
|| kind == CPTK_IS_BASE_OF
|| kind == CPTK_IS_CLASS
|| kind == CPTK_IS_CONVERTIBLE_TO
|| kind == CPTK_IS_EMPTY
|| kind == CPTK_IS_ENUM
|| kind == CPTK_IS_POD
|| kind == CPTK_IS_POLYMORPHIC
|| kind == CPTK_IS_UNION);
if (kind == CPTK_IS_CONVERTIBLE_TO)
{
sorry ("__is_convertible_to");
return error_mark_node;
}
if (type1 == error_mark_node
|| ((kind == CPTK_IS_BASE_OF || kind == CPTK_IS_CONVERTIBLE_TO)
&& type2 == error_mark_node))
return error_mark_node;
if (processing_template_decl)
{
tree trait_expr = make_node (TRAIT_EXPR);
TREE_TYPE (trait_expr) = boolean_type_node;
TRAIT_EXPR_TYPE1 (trait_expr) = type1;
TRAIT_EXPR_TYPE2 (trait_expr) = type2;
TRAIT_EXPR_KIND (trait_expr) = kind;
return trait_expr;
}
/* The only required diagnostic. */
if (kind == CPTK_IS_BASE_OF
&& NON_UNION_CLASS_TYPE_P (type1) && NON_UNION_CLASS_TYPE_P (type2)
&& !same_type_ignoring_top_level_qualifiers_p (type1, type2)
&& !COMPLETE_TYPE_P (complete_type (type2)))
{
error ("incomplete type %qT not allowed", type2);
return error_mark_node;
}
return (trait_expr_value (kind, type1, type2)
? boolean_true_node : boolean_false_node);
}
#include "gt-cp-semantics.h"

View File

@ -2293,6 +2293,12 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
*walk_subtrees_p = 0;
break;
case TRAIT_EXPR:
WALK_SUBTREE (TRAIT_EXPR_TYPE1 (*tp));
WALK_SUBTREE (TRAIT_EXPR_TYPE2 (*tp));
*walk_subtrees_p = 0;
break;
default:
return NULL_TREE;
}

View File

@ -10675,6 +10675,7 @@ Predefined Macros,cpp,The GNU C Preprocessor}).
method denoted by a @samp{->*} or @samp{.*} expression.
* C++ Attributes:: Variable, function, and type attributes for C++ only.
* Namespace Association:: Strong using-directives for namespace association.
* Type Traits:: Compiler support for type traits
* Java Exceptions:: Tweaking exception handling to work with Java.
* Deprecated Features:: Things will disappear from g++.
* Backwards Compatibility:: Compatibilities with earlier definitions of C++.
@ -11232,6 +11233,124 @@ int main()
@}
@end smallexample
@node Type Traits
@section Type Traits
The C++ front-end implements syntactic extensions that allow to
determine at compile time various characteristics of a type (or of a
pair of types).
@table @code
@item __has_nothrow_assign (type)
If @code{__has_trivial_assign (type)} is true then the trait is true, else if
@code{type} is a cv class or union type with copy assignment operators that
are known not to throw an exception then the trait is true, else it is false.
If @code{type} is const qualified, any copy assignment operator must
be both known not to throw an exception, and const qualified, for the
trait to be true. Requires: @code{type} shall be a complete type, an
array type of unknown bound, or is a @code{void} type.
@item __has_nothrow_copy (type)
If @code{__has_trivial_copy (type)} is true then the trait is true, else if
@code{type} is a cv class or union type with copy constructors that
are known not to throw an exception then the trait is true, else it is false.
Requires: @code{type} shall be a complete type, an array type of
unknown bound, or is a @code{void} type.
@item __has_nothrow_constructor (type)
If @code{__has_trivial_constructor (type)} is true then the trait is
true, else if @code{type} is a cv class or union type (or array
thereof) with a default constructor that is known not to throw an
exception then the trait is true, else it is false. Requires:
@code{type} shall be a complete type, an array type of unknown bound,
or is a @code{void} type.
@item __has_trivial_assign (type)
If @code{type} is const qualified or is a reference type then the trait is
false. Otherwise if @code{__is_pod (type)} is true then the trait is
true, else if @code{type} is a cv class or union type with a trivial
copy assignment ([class.copy]) then the trait is true, else it is
false. Requires: @code{type} shall be a complete type, an array type
of unknown bound, or is a @code{void} type.
@item __has_trivial_copy (type)
If @code{__is_pod (type)} is true or @code{type} is a reference type
then the trait is true, else if @code{type} is a cv class or union type
with a trivial copy constructor ([class.copy]) then the trait
is true, else it is false. Requires: @code{type} shall be a complete
type, an array type of unknown bound, or is a @code{void} type.
@item __has_trivial_constructor (type)
If @code{__is_pod (type)} is true then the trait is true, else if
@code{type} is a cv class or union type (or array thereof) with a
trivial default constructor ([class.ctor]) then the trait is true,
else it is false. Requires: @code{type} shall be a complete type, an
array type of unknown bound, or is a @code{void} type.
@item __has_trivial_destructor (type)
If @code{__is_pod (type)} is true or @code{type} is a reference type then
the trait is true, else if @code{type} is a cv class or union type (or
array thereof) with a trivial destructor ([class.dtor]) then the trait
is true, else it is false. Requires: @code{type} shall be a complete
type, an array type of unknown bound, or is a @code{void} type.
@item __has_virtual_destructor (type)
If @code{type} is a class type with a virtual destructor
([class.dtor]) then the trait is true, else it is false. Requires:
@code{type} shall be a complete type, an array type of unknown bound,
or is a @code{void} type.
@item __is_abstract (type)
If @code{type} is an abstract class ([class.abstract]) then the trait
is true, else it is false. Requires: @code{type} shall be a complete
type, an array type of unknown bound, or is a @code{void} type.
@item __is_base_of (base_type, derived_type)
If @code{base_type} is a base class of @code{derived_type}
([class.derived]) then the trait is true, otherwise it is false.
Top-level cv qualifications of @code{base_type} and
@code{derived_type} are ignored. For the purposes of this trait, a
class type is considered is own base. Requires: if @code{__is_class
(base_type)} and @code{__is_class (derived_type)} are true and
@code{base_type} and @code{derived_type} are not the same type
(disregarding cv-qualifiers), @code{derived_type} shall be a complete
type. Diagnostic is produced if this requirement is not met.
@item __is_class (type)
If @code{type} is a cv class type, and not a union type
([basic.compound]) the the trait is true, else it is false.
@item __is_empty (type)
If @code{__is_class (type)} is false then the trait is false.
Otherwise @code{type} is considered empty if and only if: @code{type}
has no non-static data members, or all non-static data members, if
any, are bit-fields of lenght 0, and @code{type} has no virtual
members, and @code{type} has no virtual base classes, and @code{type}
has no base classes @code{base_type} for which
@code{__is_empty (base_type)} is false. Requires: @code{type} shall
be a complete type, an array type of unknown bound, or is a
@code{void} type.
@item __is_enum (type)
If @code{type} is a cv enumeration type ([basic.compound]) the the trait is
true, else it is false.
@item __is_pod (type)
If @code{type} is a cv POD type ([basic.types]) then the trait is true,
else it is false. Requires: @code{type} shall be a complete type,
an array type of unknown bound, or is a @code{void} type.
@item __is_polymorphic (type)
If @code{type} is a polymorphic class ([class.virtual]) then the trait
is true, else it is false. Requires: @code{type} shall be a complete
type, an array type of unknown bound, or is a @code{void} type.
@item __is_union (type)
If @code{type} is a cv union type ([basic.compound]) the the trait is
true, else it is false.
@end table
@node Java Exceptions
@section Java Exceptions

View File

@ -1,3 +1,26 @@
2007-03-30 Paolo Carlini <pcarlini@suse.de>
PR c++/26099
* g++.dg/ext/is_base_of.C: New.
* g++.dg/ext/has_virtual_destructor.C: New.
* g++.dg/ext/is_polymorphic.C: New.
* g++.dg/ext/is_base_of_diagnostic.C: New.
* g++.dg/ext/is_enum.C: New.
* g++.dg/ext/has_nothrow_assign.C: New.
* g++.dg/ext/has_nothrow_constructor.C: New.
* g++.dg/ext/is_empty.C: New.
* g++.dg/ext/has_trivial_copy.C: New.
* g++.dg/ext/has_trivial_assign.C: New.
* g++.dg/ext/is_abstract.C: New.
* g++.dg/ext/is_pod.C: New.
* g++.dg/ext/has_nothrow_copy.C: New.
* g++.dg/ext/is_class.C: New.
* g++.dg/ext/has_trivial_constructor.C: New.
* g++.dg/ext/is_union.C: New.
* g++.dg/ext/has_trivial_destructor.C: New.
* g++.dg/tree-ssa/pr22444.C: Adjust, avoid __is_pod.
* g++.dg/template/crash43.C: Likewise.
2007-03-29 Dirk Mueller <dmueller@suse.de>
* g++.dg/warn/pedantic2.C: New testcase.

View File

@ -0,0 +1,152 @@
// { dg-do "run" }
#include <cassert>
struct A
{
double a;
double b;
};
struct B
{
A a;
};
struct C
: public A { };
struct D
{
D& operator=(const D&) throw() { return *this; }
};
struct E
{
E& operator=(const E&) throw(int) { return *this; }
};
struct E1
{
E1& operator=(const E1&) throw(int) { throw int(); return *this; }
};
struct F
{
F() throw(int) { }
};
struct G
{
G() throw(int) { throw int(); }
};
struct H
{
H& operator=(H&) throw(int) { return *this; }
};
struct H1
{
H1& operator=(H1&) throw(int) { throw int(); return *this; }
};
struct I
{
I& operator=(I&) throw(int) { return *this; }
I& operator=(const I&) throw() { return *this; }
};
struct I1
{
I1& operator=(I1&) throw(int) { throw int(); return *this; }
I1& operator=(const I1&) throw() { return *this; }
};
struct J
{
J& operator=(J&) throw() { return *this; }
J& operator=(const J&) throw() { return *this; }
J& operator=(volatile J&) throw() { return *this; }
J& operator=(const volatile J&) throw() { return *this; }
};
struct K
{
K& operator=(K&) throw() { return *this; }
};
struct L
{
L& operator=(const L&) throw() { return *this; }
};
template<typename T>
bool
f()
{ return __has_nothrow_assign(T); }
template<typename T>
class My
{
public:
bool
f()
{ return !!__has_nothrow_assign(T); }
};
template<typename T>
class My2
{
public:
static const bool trait = __has_nothrow_assign(T);
};
template<typename T>
const bool My2<T>::trait;
template<typename T, bool b = __has_nothrow_assign(T)>
struct My3_help
{ static const bool trait = b; };
template<typename T, bool b>
const bool My3_help<T, b>::trait;
template<typename T>
class My3
{
public:
bool
f()
{ return My3_help<T>::trait; }
};
#define PTEST(T) (__has_nothrow_assign(T) && f<T>() \
&& My<T>().f() && My2<T>::trait && My3<T>().f())
#define NTEST(T) (!__has_nothrow_assign(T) && !f<T>() \
&& !My<T>().f() && !My2<T>::trait && !My3<T>().f())
int main()
{
assert (PTEST (int));
assert (NTEST (int (int)));
assert (NTEST (void));
assert (PTEST (A));
assert (PTEST (B));
assert (PTEST (C));
assert (NTEST (C[]));
assert (PTEST (D));
assert (PTEST (E));
assert (NTEST (E1));
assert (PTEST (F));
assert (PTEST (G));
assert (PTEST (H));
assert (NTEST (H1));
assert (PTEST (I));
assert (NTEST (I1));
assert (PTEST (J));
assert (NTEST (const K));
assert (PTEST (const L));
return 0;
}

View File

@ -0,0 +1,106 @@
// { dg-do "run" }
#include <cassert>
struct A
{
double a;
double b;
};
struct B
{
A a;
};
struct C
: public A { };
struct D
{
D() throw() { }
};
struct E
{
E() throw(int) { }
};
struct E1
{
E1() throw(int) { throw int(); }
};
struct F
{
F(const F&) throw() { }
};
struct G
{
G(const G&) throw(int) { throw int(); }
};
template<typename T>
bool
f()
{ return __has_nothrow_constructor(T); }
template<typename T>
class My
{
public:
bool
f()
{ return !!__has_nothrow_constructor(T); }
};
template<typename T>
class My2
{
public:
static const bool trait = __has_nothrow_constructor(T);
};
template<typename T>
const bool My2<T>::trait;
template<typename T, bool b = __has_nothrow_constructor(T)>
struct My3_help
{ static const bool trait = b; };
template<typename T, bool b>
const bool My3_help<T, b>::trait;
template<typename T>
class My3
{
public:
bool
f()
{ return My3_help<T>::trait; }
};
#define PTEST(T) (__has_nothrow_constructor(T) && f<T>() \
&& My<T>().f() && My2<T>::trait && My3<T>().f())
#define NTEST(T) (!__has_nothrow_constructor(T) && !f<T>() \
&& !My<T>().f() && !My2<T>::trait && !My3<T>().f())
int main()
{
assert (PTEST (int));
assert (NTEST (int (int)));
assert (NTEST (void));
assert (PTEST (A));
assert (PTEST (B));
assert (PTEST (C));
assert (PTEST (C[]));
assert (PTEST (D));
assert (PTEST (E));
assert (NTEST (E1));
assert (NTEST (F));
assert (NTEST (G));
return 0;
}

View File

@ -0,0 +1,140 @@
// { dg-do "run" }
#include <cassert>
struct A
{
double a;
double b;
};
struct B
{
A a;
};
struct C
: public A { };
struct D
{
D(const D&) throw() { }
};
struct E
{
E(const E&) throw(int) { }
};
struct E1
{
E1(const E1&) throw(int) { throw int(); }
};
struct F
{
F() throw() { }
};
struct G
{
G() throw(int) { throw int(); }
};
struct H
{
H(H&) throw(int) { }
};
struct H1
{
H1(H1&) throw(int) { throw int(); }
};
struct I
{
I(I&) throw(int) { }
I(const I&) throw() { }
};
struct I1
{
I1(I1&) throw(int) { throw int(); }
I1(const I1&) throw() { }
};
struct J
{
J(J&) throw() { }
J(const J&) throw() { }
J(volatile J&) throw() { }
J(const volatile J&) throw() { }
};
template<typename T>
bool
f()
{ return __has_nothrow_copy(T); }
template<typename T>
class My
{
public:
bool
f()
{ return !!__has_nothrow_copy(T); }
};
template<typename T>
class My2
{
public:
static const bool trait = __has_nothrow_copy(T);
};
template<typename T>
const bool My2<T>::trait;
template<typename T, bool b = __has_nothrow_copy(T)>
struct My3_help
{ static const bool trait = b; };
template<typename T, bool b>
const bool My3_help<T, b>::trait;
template<typename T>
class My3
{
public:
bool
f()
{ return My3_help<T>::trait; }
};
#define PTEST(T) (__has_nothrow_copy(T) && f<T>() \
&& My<T>().f() && My2<T>::trait && My3<T>().f())
#define NTEST(T) (!__has_nothrow_copy(T) && !f<T>() \
&& !My<T>().f() && !My2<T>::trait && !My3<T>().f())
int main()
{
assert (PTEST (int));
assert (NTEST (int (int)));
assert (NTEST (void));
assert (PTEST (A));
assert (PTEST (B));
assert (PTEST (C));
assert (NTEST (C[]));
assert (PTEST (D));
assert (PTEST (E));
assert (NTEST (E1));
assert (PTEST (F));
assert (PTEST (G));
assert (PTEST (H));
assert (NTEST (H1));
assert (PTEST (I));
assert (NTEST (I1));
assert (PTEST (J));
return 0;
}

View File

@ -0,0 +1,106 @@
// { dg-do "run" }
#include <cassert>
struct A
{
double a;
double b;
};
union U
{
double a;
double b;
};
struct B
{
B& operator=(const B&) { return *this;}
};
struct C
{
virtual int f() { return 1; }
};
struct D
: public B { };
struct E
: public A { };
struct F
{
A a;
};
struct G
{
B b;
};
template<typename T>
bool
f()
{ return __has_trivial_assign(T); }
template<typename T>
class My
{
public:
bool
f()
{ return !!__has_trivial_assign(T); }
};
template<typename T>
class My2
{
public:
static const bool trait = __has_trivial_assign(T);
};
template<typename T>
const bool My2<T>::trait;
template<typename T, bool b = __has_trivial_assign(T)>
struct My3_help
{ static const bool trait = b; };
template<typename T, bool b>
const bool My3_help<T, b>::trait;
template<typename T>
class My3
{
public:
bool
f()
{ return My3_help<T>::trait; }
};
#define PTEST(T) (__has_trivial_assign(T) && f<T>() \
&& My<T>().f() && My2<T>::trait && My3<T>().f())
#define NTEST(T) (!__has_trivial_assign(T) && !f<T>() \
&& !My<T>().f() && !My2<T>::trait && !My3<T>().f())
int main()
{
assert (PTEST (int));
assert (NTEST (int (int)));
assert (NTEST (void));
assert (PTEST (A));
assert (PTEST (U));
assert (NTEST (B));
assert (NTEST (C));
assert (NTEST (D));
assert (PTEST (E));
assert (NTEST (E[]));
assert (PTEST (F));
assert (NTEST (G));
assert (NTEST (const A));
assert (NTEST (A&));
return 0;
}

View File

@ -0,0 +1,98 @@
// { dg-do "run" }
#include <cassert>
struct A
{
double a;
double b;
};
union U
{
double a;
double b;
};
struct B
{
B() { }
};
struct C
: public B { };
struct D
: public A { };
struct E
{
A a;
};
struct F
{
B b;
};
template<typename T>
bool
f()
{ return __has_trivial_constructor(T); }
template<typename T>
class My
{
public:
bool
f()
{ return !!__has_trivial_constructor(T); }
};
template<typename T>
class My2
{
public:
static const bool trait = __has_trivial_constructor(T);
};
template<typename T>
const bool My2<T>::trait;
template<typename T, bool b = __has_trivial_constructor(T)>
struct My3_help
{ static const bool trait = b; };
template<typename T, bool b>
const bool My3_help<T, b>::trait;
template<typename T>
class My3
{
public:
bool
f()
{ return My3_help<T>::trait; }
};
#define PTEST(T) (__has_trivial_constructor(T) && f<T>() \
&& My<T>().f() && My2<T>::trait && My3<T>().f())
#define NTEST(T) (!__has_trivial_constructor(T) && !f<T>() \
&& !My<T>().f() && !My2<T>::trait && !My3<T>().f())
int main()
{
assert (PTEST (int));
assert (NTEST (int (int)));
assert (NTEST (void));
assert (PTEST (A));
assert (PTEST (U));
assert (NTEST (B));
assert (NTEST (C));
assert (PTEST (D));
assert (PTEST (D[]));
assert (PTEST (E));
assert (NTEST (F));
return 0;
}

View File

@ -0,0 +1,105 @@
// { dg-do "run" }
#include <cassert>
struct A
{
double a;
double b;
};
union U
{
double a;
double b;
};
struct B
{
B(const B&) { }
};
struct C
{
virtual int f() { return 1; }
};
struct D
: public B { };
struct E
: public A { };
struct F
{
A a;
};
struct G
{
B b;
};
template<typename T>
bool
f()
{ return __has_trivial_copy(T); }
template<typename T>
class My
{
public:
bool
f()
{ return !!__has_trivial_copy(T); }
};
template<typename T>
class My2
{
public:
static const bool trait = __has_trivial_copy(T);
};
template<typename T>
const bool My2<T>::trait;
template<typename T, bool b = __has_trivial_copy(T)>
struct My3_help
{ static const bool trait = b; };
template<typename T, bool b>
const bool My3_help<T, b>::trait;
template<typename T>
class My3
{
public:
bool
f()
{ return My3_help<T>::trait; }
};
#define PTEST(T) (__has_trivial_copy(T) && f<T>() \
&& My<T>().f() && My2<T>::trait && My3<T>().f())
#define NTEST(T) (!__has_trivial_copy(T) && !f<T>() \
&& !My<T>().f() && !My2<T>::trait && !My3<T>().f())
int main()
{
assert (PTEST (int));
assert (NTEST (int (int)));
assert (NTEST (void));
assert (PTEST (A));
assert (PTEST (U));
assert (NTEST (B));
assert (NTEST (C));
assert (NTEST (D));
assert (PTEST (E));
assert (NTEST (E[]));
assert (PTEST (F));
assert (NTEST (G));
assert (PTEST (B&));
return 0;
}

View File

@ -0,0 +1,86 @@
// { dg-do "run" }
#include <cassert>
struct A
{
double a;
double b;
};
union U
{
double a;
double b;
};
struct B
{
~B() { }
};
struct C
: public B { };
struct D
: public A { };
template<typename T>
bool
f()
{ return __has_trivial_destructor(T); }
template<typename T>
class My
{
public:
bool
f()
{ return !!__has_trivial_destructor(T); }
};
template<typename T>
class My2
{
public:
static const bool trait = __has_trivial_destructor(T);
};
template<typename T>
const bool My2<T>::trait;
template<typename T, bool b = __has_trivial_destructor(T)>
struct My3_help
{ static const bool trait = b; };
template<typename T, bool b>
const bool My3_help<T, b>::trait;
template<typename T>
class My3
{
public:
bool
f()
{ return My3_help<T>::trait; }
};
#define PTEST(T) (__has_trivial_destructor(T) && f<T>() \
&& My<T>().f() && My2<T>::trait && My3<T>().f())
#define NTEST(T) (!__has_trivial_destructor(T) && !f<T>() \
&& !My<T>().f() && !My2<T>::trait && !My3<T>().f())
int main()
{
assert (PTEST (int));
assert (NTEST (int (int)));
assert (NTEST (void));
assert (PTEST (A));
assert (PTEST (U));
assert (NTEST (B));
assert (NTEST (C));
assert (PTEST (D));
assert (PTEST (D[]));
return 0;
}

View File

@ -0,0 +1,89 @@
// { dg-do "run" }
#include <cassert>
#include <exception>
struct A
{
double a;
double b;
};
union U
{
double a;
double b;
};
class B
{
virtual ~B() { }
};
class C
: public B { };
class D
{
~D() { }
};
template<typename T>
bool
f()
{ return __has_virtual_destructor(T); }
template<typename T>
class My
{
public:
bool
f()
{ return !!__has_virtual_destructor(T); }
};
template<typename T>
class My2
{
public:
static const bool trait = __has_virtual_destructor(T);
};
template<typename T>
const bool My2<T>::trait;
template<typename T, bool b = __has_virtual_destructor(T)>
struct My3_help
{ static const bool trait = b; };
template<typename T, bool b>
const bool My3_help<T, b>::trait;
template<typename T>
class My3
{
public:
bool
f()
{ return My3_help<T>::trait; }
};
#define PTEST(T) (__has_virtual_destructor(T) && f<T>() \
&& My<T>().f() && My2<T>::trait && My3<T>().f())
#define NTEST(T) (!__has_virtual_destructor(T) && !f<T>() \
&& !My<T>().f() && !My2<T>::trait && !My3<T>().f())
int main()
{
assert (NTEST (int));
assert (NTEST (void));
assert (PTEST (std::exception));
assert (NTEST (A));
assert (NTEST (U));
assert (PTEST (B));
assert (PTEST (C));
assert (NTEST (C[]));
assert (NTEST (D));
return 0;
}

View File

@ -0,0 +1,89 @@
// { dg-do "run" }
#include <cassert>
struct A
{
double a;
double b;
};
union U
{
double a;
double b;
};
class B
{
B();
};
class C
{
virtual void rotate(int) = 0;
};
class D
{
virtual void rotate(int) { }
};
template<typename T>
bool
f()
{ return __is_abstract(T); }
template<typename T>
class My
{
public:
bool
f()
{ return !!__is_abstract(T); }
};
template<typename T>
class My2
{
public:
static const bool trait = __is_abstract(T);
};
template<typename T>
const bool My2<T>::trait;
template<typename T, bool b = __is_abstract(T)>
struct My3_help
{ static const bool trait = b; };
template<typename T, bool b>
const bool My3_help<T, b>::trait;
template<typename T>
class My3
{
public:
bool
f()
{ return My3_help<T>::trait; }
};
#define PTEST(T) (__is_abstract(T) && f<T>() \
&& My<T>().f() && My2<T>::trait && My3<T>().f())
#define NTEST(T) (!__is_abstract(T) && !f<T>() \
&& !My<T>().f() && !My2<T>::trait && !My3<T>().f())
int main()
{
assert (NTEST (int));
assert (NTEST (void));
assert (NTEST (A));
assert (NTEST (U));
assert (NTEST (B));
assert (NTEST (B[]));
assert (PTEST (C));
assert (NTEST (D));
return 0;
}

View File

@ -0,0 +1,94 @@
// { dg-do "run" }
#include <cassert>
class A1
{
double a;
double b;
};
class A2
{
double a;
double b;
};
class B
: private A1 { };
class C
: private A1, private A2 { };
union U
{
double a;
double b;
};
template<typename T, typename U>
bool
f()
{ return __is_base_of(T, U); }
template<typename T, typename U>
class My
{
public:
bool
f()
{ return !!__is_base_of(T, U); }
};
template<typename T, typename U>
class My2
{
public:
static const bool trait = __is_base_of(T, U);
};
template<typename T, typename U>
const bool My2<T, U>::trait;
template<typename T, typename U, bool b = __is_base_of(T, U)>
struct My3_help
{ static const bool trait = b; };
template<typename T, typename U, bool b>
const bool My3_help<T, U, b>::trait;
template<typename T, typename U>
class My3
{
public:
bool
f()
{ return My3_help<T, U>::trait; }
};
#define PTEST(T, U) (__is_base_of(T, U) && f<T, U>() \
&& My<T, U>().f() && My2<T, U>::trait && My3<T, U>().f())
#define NTEST(T, U) (!__is_base_of(T, U) && !f<T, U>() \
&& !My<T, U>().f() && !My2<T, U>::trait && !My3<T, U>().f())
int main()
{
assert (NTEST (int, A1));
assert (NTEST (A1, void));
assert (PTEST (A1, A1));
assert (NTEST (A1*, A1*));
assert (NTEST (A1&, A1&));
assert (PTEST (A1, B));
assert (NTEST (B, A1));
assert (PTEST (A1, C));
assert (PTEST (A2, C));
assert (NTEST (C, A1));
assert (PTEST (A1, const B));
assert (NTEST (const B, A1));
assert (PTEST (A1, volatile C));
assert (PTEST (volatile A2, const C));
assert (NTEST (const volatile C, A1));
assert (NTEST (U, U));
return 0;
}

View File

@ -0,0 +1,15 @@
class A
{ };
class B;
union C
{ };
union D;
void f()
{
__is_base_of(A, B); // { dg-error "incomplete type" }
__is_base_of(C, D);
}

View File

@ -0,0 +1,76 @@
// { dg-do "run" }
#include <cassert>
struct A
{
double a;
double b;
};
class B
{
B() { }
};
union U
{
double a;
double b;
};
template<typename T>
bool
f()
{ return __is_class(T); }
template<typename T>
class My
{
public:
bool
f()
{ return !!__is_class(T); }
};
template<typename T>
class My2
{
public:
static const bool trait = __is_class(T);
};
template<typename T>
const bool My2<T>::trait;
template<typename T, bool b = __is_class(T)>
struct My3_help
{ static const bool trait = b; };
template<typename T, bool b>
const bool My3_help<T, b>::trait;
template<typename T>
class My3
{
public:
bool
f()
{ return My3_help<T>::trait; }
};
#define PTEST(T) (__is_class(T) && f<T>() \
&& My<T>().f() && My2<T>::trait && My3<T>().f())
#define NTEST(T) (!__is_class(T) && !f<T>() \
&& !My<T>().f() && !My2<T>::trait && !My3<T>().f())
int main()
{
assert (NTEST (int));
assert (NTEST (void));
assert (PTEST (A));
assert (PTEST (B));
assert (NTEST (U));
return 0;
}

View File

@ -0,0 +1,78 @@
// { dg-do "run" }
#include <cassert>
struct A
{
double a;
double b;
};
struct B
{
virtual ~B() { }
};
class C
{ };
union U
{ };
template<typename T>
bool
f()
{ return __is_empty(T); }
template<typename T>
class My
{
public:
bool
f()
{ return !!__is_empty(T); }
};
template<typename T>
class My2
{
public:
static const bool trait = __is_empty(T);
};
template<typename T>
const bool My2<T>::trait;
template<typename T, bool b = __is_empty(T)>
struct My3_help
{ static const bool trait = b; };
template<typename T, bool b>
const bool My3_help<T, b>::trait;
template<typename T>
class My3
{
public:
bool
f()
{ return My3_help<T>::trait; }
};
#define PTEST(T) (__is_empty(T) && f<T>() \
&& My<T>().f() && My2<T>::trait && My3<T>().f())
#define NTEST(T) (!__is_empty(T) && !f<T>() \
&& !My<T>().f() && !My2<T>::trait && !My3<T>().f())
int main()
{
assert (NTEST (int));
assert (NTEST (void));
assert (NTEST (A));
assert (NTEST (B));
assert (PTEST (C));
assert (NTEST (C[]));
assert (NTEST (U));
return 0;
}

View File

@ -0,0 +1,73 @@
// { dg-do "run" }
#include <cassert>
struct A
{
double a;
double b;
};
class B
{ };
enum E
{
e0
};
template<typename T>
bool
f()
{ return __is_enum(T); }
template<typename T>
class My
{
public:
bool
f()
{ return !!__is_enum(T); }
};
template<typename T>
class My2
{
public:
static const bool trait = __is_enum(T);
};
template<typename T>
const bool My2<T>::trait;
template<typename T, bool b = __is_enum(T)>
struct My3_help
{ static const bool trait = b; };
template<typename T, bool b>
const bool My3_help<T, b>::trait;
template<typename T>
class My3
{
public:
bool
f()
{ return My3_help<T>::trait; }
};
#define PTEST(T) (__is_enum(T) && f<T>() \
&& My<T>().f() && My2<T>::trait && My3<T>().f())
#define NTEST(T) (!__is_enum(T) && !f<T>() \
&& !My<T>().f() && !My2<T>::trait && !My3<T>().f())
int main()
{
assert (NTEST (int));
assert (NTEST (void));
assert (NTEST (A));
assert (NTEST (B));
assert (PTEST (E));
return 0;
}

View File

@ -0,0 +1,75 @@
// { dg-do "run" }
#include <cassert>
struct A
{
double a;
double b;
};
struct B
{
B() { }
};
struct C
: public A { };
template<typename T>
bool
f()
{ return __is_pod(T); }
template<typename T>
class My
{
public:
bool
f()
{ return !!__is_pod(T); }
};
template<typename T>
class My2
{
public:
static const bool trait = __is_pod(T);
};
template<typename T>
const bool My2<T>::trait;
template<typename T, bool b = __is_pod(T)>
struct My3_help
{ static const bool trait = b; };
template<typename T, bool b>
const bool My3_help<T, b>::trait;
template<typename T>
class My3
{
public:
bool
f()
{ return My3_help<T>::trait; }
};
#define PTEST(T) (__is_pod(T) && f<T>() \
&& My<T>().f() && My2<T>::trait && My3<T>().f())
#define NTEST(T) (!__is_pod(T) && !f<T>() \
&& !My<T>().f() && !My2<T>::trait && !My3<T>().f())
int main()
{
assert (PTEST (int));
assert (NTEST (void));
assert (PTEST (A));
assert (PTEST (A[]));
assert (NTEST (B));
assert (NTEST (C));
assert (NTEST (C[]));
return 0;
}

View File

@ -0,0 +1,83 @@
// { dg-do "run" }
#include <cassert>
#include <exception>
struct A
{
double a;
double b;
};
class B
{
virtual void rotate(int) { }
};
class C
: public B { };
union U
{
double a;
double b;
};
template<typename T>
bool
f()
{ return __is_polymorphic(T); }
template<typename T>
class My
{
public:
bool
f()
{ return !!__is_polymorphic(T); }
};
template<typename T>
class My2
{
public:
static const bool trait = __is_polymorphic(T);
};
template<typename T>
const bool My2<T>::trait;
template<typename T, bool b = __is_polymorphic(T)>
struct My3_help
{ static const bool trait = b; };
template<typename T, bool b>
const bool My3_help<T, b>::trait;
template<typename T>
class My3
{
public:
bool
f()
{ return My3_help<T>::trait; }
};
#define PTEST(T) (__is_polymorphic(T) && f<T>() \
&& My<T>().f() && My2<T>::trait && My3<T>().f())
#define NTEST(T) (!__is_polymorphic(T) && !f<T>() \
&& !My<T>().f() && !My2<T>::trait && !My3<T>().f())
int main()
{
assert (NTEST (int));
assert (NTEST (void));
assert (PTEST (std::exception));
assert (NTEST (A));
assert (PTEST (B));
assert (PTEST (C));
assert (NTEST (C[]));
assert (NTEST (U));
return 0;
}

View File

@ -0,0 +1,76 @@
// { dg-do "run" }
#include <cassert>
struct A
{
double a;
double b;
};
class B
{
B() { }
};
union U
{
double a;
double b;
};
template<typename T>
bool
f()
{ return __is_union(T); }
template<typename T>
class My
{
public:
bool
f()
{ return !!__is_union(T); }
};
template<typename T>
class My2
{
public:
static const bool trait = __is_union(T);
};
template<typename T>
const bool My2<T>::trait;
template<typename T, bool b = __is_union(T)>
struct My3_help
{ static const bool trait = b; };
template<typename T, bool b>
const bool My3_help<T, b>::trait;
template<typename T>
class My3
{
public:
bool
f()
{ return My3_help<T>::trait; }
};
#define PTEST(T) (__is_union(T) && f<T>() \
&& My<T>().f() && My2<T>::trait && My3<T>().f())
#define NTEST(T) (!__is_union(T) && !f<T>() \
&& !My<T>().f() && !My2<T>::trait && !My3<T>().f())
int main()
{
assert (NTEST (int));
assert (NTEST (void));
assert (NTEST (A));
assert (NTEST (B));
assert (PTEST (U));
return 0;
}

View File

@ -2,7 +2,7 @@
extern "C" {
template<typename _Tp> // { dg-error "C" }
struct __is_pod {
struct ___is_pod {
enum {
__value = (sizeof(__gnu_internal::__test_type<_Tp>(0)))}; // { dg-error "declared|expected" }

View File

@ -22,7 +22,7 @@ namespace __gnu_internal
}
namespace std
{
template<typename _Tp> struct __is_pod
template<typename _Tp> struct ___is_pod
{
enum { __value = (sizeof(__gnu_internal::__test_type<_Tp>(0))!= sizeof(__gnu_internal::__one)) };
};
@ -111,7 +111,7 @@ namespace std
typedef _Val value_type;
typedef value_type* pointer;
typedef _Rb_tree_node* _Link_type;
template<typename _Key_compare, bool _Is_pod_comparator = std::__is_pod<_Key_compare>::__value> struct _Rb_tree_impl
template<typename _Key_compare, bool _Is_pod_comparator = std::___is_pod<_Key_compare>::__value> struct _Rb_tree_impl
: _Node_allocator
{
_Rb_tree_node_base _M_header;

View File

@ -1,3 +1,12 @@
2007-03-30 Paolo Carlini <pcarlini@suse.de>
PR c++/26099
* include/bits/cpp_type_traits.h (struct __is_pod, struct __is_empty):
Remove.
* include/bits/valarray_array.h: Adjust.
* include/bits/allocator.h: Likewise.
* include/bits/stl_tree.h: Likewise.
2007-03-30 Paolo Carlini <pcarlini@suse.de>
PR libstdc++/31401

View File

@ -1,6 +1,6 @@
// Allocators -*- C++ -*-
// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006
// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
@ -132,7 +132,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
#undef __glibcxx_base_allocator
// To implement Option 3 of DR 431.
template<typename _Alloc, bool = std::__is_empty<_Alloc>::__value>
template<typename _Alloc, bool = __is_empty(_Alloc)>
struct __alloc_swap
{ static void _S_do_it(_Alloc&, _Alloc&) { } };

View File

@ -1,6 +1,6 @@
// The -*- C++ -*- type traits classes for internal use in libstdc++
// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006
// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
@ -80,20 +80,6 @@ _GLIBCXX_END_NAMESPACE
_GLIBCXX_BEGIN_NAMESPACE(std)
namespace __detail
{
// NB: g++ can not compile these if declared within the class
// __is_pod itself.
typedef char __one;
typedef char __two[2];
template<typename _Tp>
__one __test_type(int _Tp::*);
template<typename _Tp>
__two& __test_type(...);
} // namespace __detail
struct __true_type { };
struct __false_type { };
@ -341,37 +327,6 @@ namespace __detail
: public __traitor<__is_arithmetic<_Tp>, __is_pointer<_Tp> >
{ };
// For the immediate use, the following is a good approximation.
template<typename _Tp>
struct __is_pod
{
enum
{
__value = (sizeof(__detail::__test_type<_Tp>(0))
!= sizeof(__detail::__one))
};
};
//
// A stripped-down version of std::tr1::is_empty
//
template<typename _Tp>
struct __is_empty
{
private:
template<typename>
struct __first { };
template<typename _Up>
struct __second
: public _Up { };
public:
enum
{
__value = sizeof(__first<_Tp>) == sizeof(__second<_Tp>)
};
};
//
// For use in std::copy and std::find overloads for streambuf iterators.
//

View File

@ -393,7 +393,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
protected:
template<typename _Key_compare,
bool _Is_pod_comparator = std::__is_pod<_Key_compare>::__value>
bool _Is_pod_comparator = __is_pod(_Key_compare)>
struct _Rb_tree_impl : public _Node_allocator
{
_Key_compare _M_key_compare;

View File

@ -1,6 +1,6 @@
// The template and inlines for the -*- C++ -*- internal _Array helper class.
// Copyright (C) 1997, 1998, 1999, 2000, 2003, 2004, 2005, 2006
// Copyright (C) 1997, 1998, 1999, 2000, 2003, 2004, 2005, 2006, 2007
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
@ -98,7 +98,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
inline void
__valarray_default_construct(_Tp* __restrict__ __b, _Tp* __restrict__ __e)
{
_Array_default_ctor<_Tp, __is_pod<_Tp>::__value>::_S_do_it(__b, __e);
_Array_default_ctor<_Tp, __is_pod(_Tp)>::_S_do_it(__b, __e);
}
// Turn a raw-memory into an array of _Tp filled with __t
@ -133,7 +133,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
__valarray_fill_construct(_Tp* __restrict__ __b, _Tp* __restrict__ __e,
const _Tp __t)
{
_Array_init_ctor<_Tp, __is_pod<_Tp>::__value>::_S_do_it(__b, __e, __t);
_Array_init_ctor<_Tp, __is_pod(_Tp)>::_S_do_it(__b, __e, __t);
}
//
@ -169,7 +169,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
const _Tp* __restrict__ __e,
_Tp* __restrict__ __o)
{
_Array_copy_ctor<_Tp, __is_pod<_Tp>::__value>::_S_do_it(__b, __e, __o);
_Array_copy_ctor<_Tp, __is_pod(_Tp)>::_S_do_it(__b, __e, __o);
}
// copy-construct raw array [__o, *) from strided array __a[<__n : __s>]
@ -178,7 +178,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
__valarray_copy_construct (const _Tp* __restrict__ __a, size_t __n,
size_t __s, _Tp* __restrict__ __o)
{
if (__is_pod<_Tp>::__value)
if (__is_pod(_Tp))
while (__n--)
{
*__o++ = *__a;
@ -199,7 +199,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
const size_t* __restrict__ __i,
_Tp* __restrict__ __o, size_t __n)
{
if (__is_pod<_Tp>::__value)
if (__is_pod(_Tp))
while (__n--)
*__o++ = __a[*__i++];
else
@ -212,7 +212,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
inline void
__valarray_destroy_elements(_Tp* __restrict__ __b, _Tp* __restrict__ __e)
{
if (!__is_pod<_Tp>::__value)
if (!__is_pod(_Tp))
while (__b != __e)
{
__b->~_Tp();
@ -276,7 +276,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
__valarray_copy(const _Tp* __restrict__ __a, size_t __n,
_Tp* __restrict__ __b)
{
_Array_copier<_Tp, __is_pod<_Tp>::__value>::_S_do_it(__a, __n, __b);
_Array_copier<_Tp, __is_pod(_Tp)>::_S_do_it(__a, __n, __b);
}
// Copy strided array __a[<__n : __s>] in plain __b[<__n>]