From: <rom...@us...> - 2008-06-23 20:13:54
|
Revision: 1340 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1340&view=rev Author: roman_yakovenko Date: 2008-06-23 13:14:02 -0700 (Mon, 23 Jun 2008) Log Message: ----------- changing some of type_traits functions - adding support for artificial declarations Modified Paths: -------------- pygccxml_dev/pygccxml/declarations/type_traits.py Modified: pygccxml_dev/pygccxml/declarations/type_traits.py =================================================================== --- pygccxml_dev/pygccxml/declarations/type_traits.py 2008-06-23 20:10:56 UTC (rev 1339) +++ pygccxml_dev/pygccxml/declarations/type_traits.py 2008-06-23 20:14:02 UTC (rev 1340) @@ -111,7 +111,7 @@ def is_bool( type_ ): """returns True, if type represents C{bool}, False otherwise""" return remove_alias( type_ ) in create_cv_types( cpptypes.bool_t() ) - + def is_void( type ): """returns True, if type represents C{void}, False otherwise""" return remove_alias( type ) in create_cv_types( cpptypes.void_t() ) @@ -213,7 +213,7 @@ return remove_pointer( type_ ) else: assert 0 - + def remove_reference(type): """removes reference from the type definition @@ -348,115 +348,46 @@ assert isinstance( type, class_declaration.class_t ) return type.find_trivial_constructor() -def has_trivial_constructor( type ): - """returns True, if class has public trivial constructor, False otherwise""" - logger = utils.loggers.cxx_parser - true_header = "has_trivial_constructor(TRUE)- %s - " % type.decl_string - false_header = "has_trivial_constructor(false)- %s - " % type.decl_string - - if '0.9' in type.compiler: - trivial = type.constructors( lambda x: x.is_trivial_constructor - , recursive=False - , allow_empty=True ) - if trivial: - if trivial[0].access_type == 'public': - logger.debug( true_header + "there is user defined public trivial constructor" ) - return True - else: - logger.debug( false_header + "there is user defined non-public trivial constructor" ) - return False - else: - #there is no trivial constructor, so I should find out whether other constructors exist - if type.constructors( recursive=False, allow_empty=True ): - logger.debug( false_header + "there are other user defined constructors" ) - return False - else: - if __contains_noncopyable_mem_var( type ): - logger.debug( false_header + "class doesn't have any user defined constructor and BUT it is NOT copyable" ) - return False - else: - logger.debug( true_header + "class doesn't have any user defined constructor and it is copyable" ) - return True - else: - cons = find_trivial_constructor( type ) - return cons and cons.access_type == 'public' +def has_trivial_constructor( class_ ): + """if class has public trivial constructor, this function will return reference to it, None otherwise""" + class_ = class_traits.get_declaration( class_ ) + trivial = class_.find_trivial_constructor() + if trivial and trivial.access_type == 'public': + return trivial -""" -Question: Do I have to define a copy constructor and assignment operator? - -Answer: - C++ implicitly declares a copy constructor and an assignment operator - for every class, struct and union unless the user declared them explicitly. - A copy constructor isnot implicitly declared if the class has any user-declared - constructor(s). Implicitly defined copy constructor and assignment operator - are said to be trivial if: - - * their class has no virtual functions and no virtual base class(es) - * all direct base classes and nonstatic data members of their class have trivial constructors - - Otherwise, the copy constructor and the assignment operator are non-trivial. - Implicitly-declared non-trivial copy constructor and assignment operator are - implicitly-defined. - -The assignment operator is called "copy assignment operator" in the standard. -This verbosity doesnot convey any new or hidden meanings. Perhaps it's meant to -differentiate between the assignment operator of fundamental types and the -assignment operator member function of class types. In this series I will stick -to the term assignment operator. -""" - def has_copy_constructor( class_ ): - """returns True, if class has public copy constructor, False otherwise""" + """if class has public copy constructor, this function will return reference to it, None otherwise""" class_ = class_traits.get_declaration( class_ ) - if '0.9' in class_.compiler: - copy_ = class_.find_copy_constructor() - if copy_: - if copy_.access_type == 'public': - return True - else: - return False - else: - if __contains_noncopyable_mem_var( class_ ): - return False - else: - return True - else: - constructors = filter( lambda x: isinstance( x, calldef.constructor_t ) \ - and x.is_copy_constructor - , class_.public_members ) - return bool( constructors ) + copy_constructor = class_.find_copy_constructor() + if copy_constructor and copy_constructor.access_type == 'public': + return copy_constructor -def has_destructor(type): - """returns True, if class has destructor, False otherwise""" - assert isinstance( type, class_declaration.class_t ) - return bool( algorithm.find_declaration( type.get_members() - , type=calldef.destructor_t - , recursive=False ) ) +def has_destructor(class_): + """if class has destructor, this function will return reference to it, None otherwise""" + class_ = class_traits.get_declaration( class_ ) + destructor = class_.decls( decl_type=calldef.destructor_t, recursive=False, allow_empty=True ) + if destructor: + return destructor[0] -def has_public_constructor(type): - """returns True, if class has public constructor, False otherwise""" - assert isinstance( type, class_declaration.class_t ) - decls = algorithm.find_all_declarations( type.public_members - , type=calldef.constructor_t - , recursive=False ) - constructors = filter( lambda decl: not decl.is_copy_constructor, decls ) - return bool( constructors ) or has_trivial_constructor( type ) +def has_public_constructor(class_): + """if class has any public constructor, this function will return list of them, otherwise None""" + class_ = class_traits.get_declaration(class_) + decls = class_.constructors( lambda c: not c.is_copy_constructor and c.access_type == 'public' + , recursive=False, allow_empty=True ) + if decls: + return decls -def has_public_assign(type): +def has_public_assign(class_): """returns True, if class has public assign operator, False otherwise""" - assert isinstance( type, class_declaration.class_t ) - decls = algorithm.find_all_declarations( type.public_members - , type=calldef.member_operator_t - , recursive=False ) - decls = filter( lambda decl: decl.symbol == '=', decls ) + class_ = class_traits.get_declaration( class_ ) + decls = class_.mem_opers( lambda o: o.symbol == '=' and o.access_type == 'public' + , recursive=False, allow_empty=True ) return bool( decls ) def has_public_destructor(type): """returns True, if class has public destructor, False otherwise""" - assert isinstance( type, class_declaration.class_t ) - return bool( algorithm.find_declaration( type.public_members - , type=calldef.destructor_t - , recursive=False ) ) + d = has_destructor( type ) + return d and d.access_type == 'public' def is_base_and_derived( based, derived ): """returns True, if there is "base and derived" relationship between classes, False otherwise""" @@ -468,20 +399,20 @@ all_derived = ( [derived] ) else: #tuple all_derived = derived - + for derived_cls in all_derived: for base_desc in derived_cls.recursive_bases: if base_desc.related_class == based: return True return False - + def has_any_non_copyconstructor( type): - """returns True, if class has any non "copy constructor", otherwise False""" - assert isinstance( type, class_declaration.class_t ) - constructors = filter( lambda x: isinstance( x, calldef.constructor_t ) \ - and not x.is_copy_constructor - , type.public_members ) - return bool( constructors ) or has_trivial_constructor( type ) + """if class has any public constructor, which is not copy constructor, this function will return list of them, otherwise None""" + class_ = class_traits.get_declaration( type ) + decls = class_.constructors( lambda c: not c.is_copy_constructor and c.access_type == 'public' + , recursive=False, allow_empty=True ) + if decls: + return decls def has_public_binary_operator( type, operator_symbol ): """returns True, if type has public binary operator, otherwise False""" @@ -916,18 +847,18 @@ if __contains_noncopyable_mem_var( class_ ): logger.debug( "__is_noncopyable_single(TRUE) - %s - contains noncopyable members" % class_.decl_string ) return True - else: + else: logger.debug( "__is_noncopyable_single(FALSE) - %s - COPYABLE, because is doesn't contains noncopyable members" % class_.decl_string ) return False def is_noncopyable( class_ ): """returns True, if class is noncopyable, False otherwise""" - logger = utils.loggers.cxx_parser + logger = utils.loggers.cxx_parser class_ = class_traits.get_declaration( class_ ) - + true_header = "is_noncopyable(TRUE) - %s - " % class_.decl_string false_header = "is_noncopyable(false) - %s - " % class_.decl_string - + if class_.class_type == class_declaration.CLASS_TYPES.UNION: return False @@ -935,17 +866,17 @@ logger.debug( true_header + "abstract client" ) return True - #if class has public, user defined copy constructor, than this class is + #if class has public, user defined copy constructor, than this class is #copyable copy_ = class_.find_copy_constructor() if copy_ and copy_.access_type == 'public' and not copy_.is_artificial: return False - + for base_desc in class_.recursive_bases: - assert isinstance( base_desc, class_declaration.hierarchy_info_t ) + assert isinstance( base_desc, class_declaration.hierarchy_info_t ) if base_desc.related_class.decl_string in ('::boost::noncopyable', '::boost::noncopyable_::noncopyable' ): logger.debug( true_header + "derives from boost::noncopyable" ) - return True + return True if not has_copy_constructor( base_desc.related_class ): base_copy_ = base_desc.related_class.find_copy_constructor() if base_copy_: @@ -959,7 +890,7 @@ if __is_noncopyable_single( base_desc.related_class ): logger.debug( true_header + "__is_noncopyable_single returned True" ) return True - + if not has_copy_constructor( class_ ): logger.debug( true_header + "does not have trival copy constructor" ) return True @@ -1032,9 +963,9 @@ found = global_ns.decls( name=value_type_str , function=lambda decl: not isinstance( decl, calldef.calldef_t ) , allow_empty=True ) - if not found: + if not found: no_global_ns_value_type_str = value_type_str[2:] - if cpptypes.FUNDAMENTAL_TYPES.has_key( no_global_ns_value_type_str ): + if cpptypes.FUNDAMENTAL_TYPES.has_key( no_global_ns_value_type_str ): return cpptypes.FUNDAMENTAL_TYPES[ no_global_ns_value_type_str ] elif is_std_string( value_type_str ): string_ = global_ns.typedef( '::std::string' ) @@ -1137,8 +1068,8 @@ else: type = remove_alias( type ) return remove_cv( type ).decl_string in decl_strings - + def is_std_wostream( type ): """returns True, if type represents C++ std::string, False otherwise""" decl_strings = [ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |