[pygccxml-commit] SF.net SVN: pygccxml: [1156] pygccxml_dev
Brought to you by:
mbaas,
roman_yakovenko
|
From: <rom...@us...> - 2007-11-15 15:23:30
|
Revision: 1156
http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1156&view=rev
Author: roman_yakovenko
Date: 2007-11-15 07:23:34 -0800 (Thu, 15 Nov 2007)
Log Message:
-----------
even more improving to is_noncopyable and has_trivial_constructor algorithms
Modified Paths:
--------------
pygccxml_dev/pygccxml/declarations/type_traits.py
pygccxml_dev/unittests/data/type_traits.hpp
Modified: pygccxml_dev/pygccxml/declarations/type_traits.py
===================================================================
--- pygccxml_dev/pygccxml/declarations/type_traits.py 2007-11-15 06:57:30 UTC (rev 1155)
+++ pygccxml_dev/pygccxml/declarations/type_traits.py 2007-11-15 15:23:34 UTC (rev 1156)
@@ -15,6 +15,7 @@
within this module works on L{type_t} class hierarchy and\\or L{class_t}.
"""
+import os
import types
import matchers
import typedef
@@ -26,6 +27,7 @@
import templates
import enumeration
import class_declaration
+from pygccxml import utils
import types as build_in_types
def __remove_alias(type_):
@@ -344,31 +346,37 @@
def find_trivial_constructor( type ):
"""returns reference to trivial constructor or None"""
assert isinstance( type, class_declaration.class_t )
- trivial = type.constructors( lambda x: x.is_trivial_constructor and x.access_type == 'public'
- , recursive=False
- , allow_empty=True )
- if trivial:
- return trivial[0]
- else:
- return None
+ 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:
- return True
+ 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:
if None != find_trivial_constructor( type ):
return True
@@ -862,48 +870,70 @@
"""returns True, if source could be converted to target, otherwise False"""
return __is_convertible_t( source, target ).is_convertible()
-def __is_noncopyable_single( class_ ):
+def __contains_noncopyable_mem_var( class_ ):
"""implementation details"""
- #It is not enough to check base classes, we should also to check
- #member variables.
-
- if has_trivial_copy( class_ ) \
- and has_public_constructor( class_ ) \
- and has_public_assign( class_ ) \
- and has_public_destructor( class_ ):
- return False
-
- mvars = filter( lambda x: isinstance( x, variable.variable_t )
- , class_.declarations )
+ logger = utils.loggers.cxx_parser
+ mvars = class_.vars( lambda v: not v.type_qualifiers.has_static, recursive=False, allow_empty=True )
for mvar in mvars:
- if mvar.type_qualifiers.has_static:
- continue
type_ = remove_alias( mvar.type )
type_ = remove_reference( type_ )
if is_const( type_ ):
no_const = remove_const( type_ )
if is_fundamental( no_const ) or is_enum( no_const):
- #~ print "__is_noncopyable_single - %s - containes const member variable - fundamental or enum" % class_.decl_string
+ logger.debug( "__contains_noncopyable_mem_var - %s - TRUE - containes const member variable - fundamental or enum" % class_.decl_string )
return True
if is_class( no_const ):
- #~ print "__is_noncopyable_single - %s - containes const member variable - class" % class_.decl_string
+ logger.debug( "__contains_noncopyable_mem_var - %s - TRUE - containes const member variable - class" % class_.decl_string )
return True
+ if is_array( no_const ):
+ logger.debug( "__contains_noncopyable_mem_var - %s - TRUE - containes const member variable - array" % class_.decl_string )
+ return True
if is_class( type_ ):
cls = type_.declaration
if is_noncopyable( cls ):
- #~ print "__is_noncopyable_single - %s - containes member variable - class that is not copyable" % class_.decl_string
+ logger.debug( "__contains_noncopyable_mem_var - %s - TRUE - containes member variable - class that is not copyable" % class_.decl_string )
return True
- return False
+ logger.debug( "__contains_noncopyable_mem_var - %s - false - doesn't contains noncopyable members" % class_.decl_string )
+def __is_noncopyable_single( class_ ):
+ """implementation details"""
+ #It is not enough to check base classes, we should also to check
+ #member variables.
+ logger = utils.loggers.cxx_parser
+
+ if has_trivial_copy( class_ ) \
+ and has_public_constructor( class_ ) \
+ and has_public_assign( class_ ) \
+ and has_public_destructor( class_ ):
+ msg = os.linesep.join([
+ "__is_noncopyable_single - %s - COPYABLE:" % class_.decl_string
+ , " trivial copy constructor: yes"
+ , " public constructor: yes"
+ , " public assign: yes"
+ , " public destructor: yes"
+ ])
+ logger.debug( msg )
+ return False
+ if __contains_noncopyable_mem_var( class_ ):
+ logger.debug( "__is_noncopyable_single(TRUE) - %s - contains noncopyable members" % class_.decl_string )
+ return True
+ 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
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
if class_.is_abstract:
- #~ print "is_noncopyable - %s - abstract client" % class_.decl_string
+ logger.debug( true_header + "abstract client" )
return True
#if class has public, user defined copy constructor, than this class is
@@ -915,30 +945,30 @@
for base_desc in class_.recursive_bases:
assert isinstance( base_desc, class_declaration.hierarchy_info_t )
if base_desc.related_class.decl_string in ('::boost::noncopyable', '::boost::noncopyable_::noncopyable' ):
- #~ print "is_noncopyable - %s - derives from boost::noncopyable" % class_.decl_string
+ logger.debug( true_header + "derives from boost::noncopyable" )
return True
if not has_trivial_copy( base_desc.related_class ):
base_copy_ = base_desc.related_class.find_copy_constructor()
if base_copy_:
if base_copy_.access_type == 'private':
- #~ print "is_noncopyable - %s - there is private copy constructor" % class_.decl_string
+ logger.debug( true_header + "there is private copy constructor" )
return True
else:
if __is_noncopyable_single( base_desc.related_class ):
- #~ print "is_noncopyable - %s - __is_noncopyable_single returned True" % class_.decl_string
+ logger.debug( true_header + "__is_noncopyable_single returned True" )
return True
if __is_noncopyable_single( base_desc.related_class ):
- #~ print "is_noncopyable - %s - __is_noncopyable_single returned True" % class_.decl_string
+ logger.debug( true_header + "__is_noncopyable_single returned True" )
return True
if not has_trivial_copy( class_ ):
- #~ print "is_noncopyable - %s - does not have trival copy constructor" % class_.decl_string
+ logger.debug( true_header + "does not have trival copy constructor" )
return True
elif not has_public_constructor( class_ ):
- #~ print "is_noncopyable - %s - does not have a public constructor" % class_.decl_string
+ logger.debug( true_header + "does not have a public constructor" )
return True
elif has_destructor( class_ ) and not has_public_destructor( class_ ):
- #~ print "is_noncopyable - %s - has private destructor" % class_.decl_string
+ logger.debug( true_header + "has private destructor")
return True
else:
return __is_noncopyable_single( class_ )
Modified: pygccxml_dev/unittests/data/type_traits.hpp
===================================================================
--- pygccxml_dev/unittests/data/type_traits.hpp 2007-11-15 06:57:30 UTC (rev 1155)
+++ pygccxml_dev/unittests/data/type_traits.hpp 2007-11-15 15:23:34 UTC (rev 1156)
@@ -152,7 +152,10 @@
const E e_;
};
-
+ struct const_item{ const int values[10]; };
+
+ struct const_container{ const const_item items[10]; };
+
}
namespace yes{
@@ -163,7 +166,9 @@
typedef detail::d_t d_t;
typedef detail::dd_t dd_t;
typedef detail::f_t f_t;
- typedef detail::g_t g_t;
+ typedef detail::g_t g_t;
+ typedef detail::const_item const_item_t;
+ typedef detail::const_container const_container_t;
}
namespace no{
typedef std::string string_type;
@@ -499,6 +504,7 @@
} }
namespace has_trivial_constructor{
+
namespace yes{
struct x{
x(){}
@@ -510,6 +516,10 @@
private:
y(){}
};
+
+ struct const_item{ const int values[10]; };
+ struct const_container{ const const_item items[10]; };
+
} }
namespace has_public_constructor{
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|