@@ -111,7 +111,7 @@ def does_match_definition(given, main, secondary ):
111
111
def is_bool ( type_ ):
112
112
"""returns True, if type represents C{bool}, False otherwise"""
113
113
return remove_alias ( type_ ) in create_cv_types ( cpptypes .bool_t () )
114
-
114
+
115
115
def is_void ( type ):
116
116
"""returns True, if type represents C{void}, False otherwise"""
117
117
return remove_alias ( type ) in create_cv_types ( cpptypes .void_t () )
@@ -213,7 +213,7 @@ def array_item_type(type_):
213
213
return remove_pointer ( type_ )
214
214
else :
215
215
assert 0
216
-
216
+
217
217
def remove_reference (type ):
218
218
"""removes reference from the type definition
219
219
@@ -348,115 +348,46 @@ def find_trivial_constructor( type ):
348
348
assert isinstance ( type , class_declaration .class_t )
349
349
return type .find_trivial_constructor ()
350
350
351
- def has_trivial_constructor ( type ):
352
- """returns True, if class has public trivial constructor, False otherwise"""
353
- logger = utils .loggers .cxx_parser
354
- true_header = "has_trivial_constructor(TRUE)- %s - " % type .decl_string
355
- false_header = "has_trivial_constructor(false)- %s - " % type .decl_string
356
-
357
- if '0.9' in type .compiler :
358
- trivial = type .constructors ( lambda x : x .is_trivial_constructor
359
- , recursive = False
360
- , allow_empty = True )
361
- if trivial :
362
- if trivial [0 ].access_type == 'public' :
363
- logger .debug ( true_header + "there is user defined public trivial constructor" )
364
- return True
365
- else :
366
- logger .debug ( false_header + "there is user defined non-public trivial constructor" )
367
- return False
368
- else :
369
- #there is no trivial constructor, so I should find out whether other constructors exist
370
- if type .constructors ( recursive = False , allow_empty = True ):
371
- logger .debug ( false_header + "there are other user defined constructors" )
372
- return False
373
- else :
374
- if __contains_noncopyable_mem_var ( type ):
375
- logger .debug ( false_header + "class doesn't have any user defined constructor and BUT it is NOT copyable" )
376
- return False
377
- else :
378
- logger .debug ( true_header + "class doesn't have any user defined constructor and it is copyable" )
379
- return True
380
- else :
381
- cons = find_trivial_constructor ( type )
382
- return cons and cons .access_type == 'public'
383
-
384
- """
385
- Question: Do I have to define a copy constructor and assignment operator?
386
-
387
- Answer:
388
- C++ implicitly declares a copy constructor and an assignment operator
389
- for every class, struct and union unless the user declared them explicitly.
390
- A copy constructor isnot implicitly declared if the class has any user-declared
391
- constructor(s). Implicitly defined copy constructor and assignment operator
392
- are said to be trivial if:
393
-
394
- * their class has no virtual functions and no virtual base class(es)
395
- * all direct base classes and nonstatic data members of their class have trivial constructors
396
-
397
- Otherwise, the copy constructor and the assignment operator are non-trivial.
398
- Implicitly-declared non-trivial copy constructor and assignment operator are
399
- implicitly-defined.
400
-
401
- The assignment operator is called "copy assignment operator" in the standard.
402
- This verbosity doesnot convey any new or hidden meanings. Perhaps it's meant to
403
- differentiate between the assignment operator of fundamental types and the
404
- assignment operator member function of class types. In this series I will stick
405
- to the term assignment operator.
406
- """
351
+ def has_trivial_constructor ( class_ ):
352
+ """if class has public trivial constructor, this function will return reference to it, None otherwise"""
353
+ class_ = class_traits .get_declaration ( class_ )
354
+ trivial = class_ .find_trivial_constructor ()
355
+ if trivial and trivial .access_type == 'public' :
356
+ return trivial
407
357
408
358
def has_copy_constructor ( class_ ):
409
- """returns True, if class has public copy constructor, False otherwise"""
359
+ """if class has public copy constructor, this function will return reference to it, None otherwise"""
410
360
class_ = class_traits .get_declaration ( class_ )
411
- if '0.9' in class_ .compiler :
412
- copy_ = class_ .find_copy_constructor ()
413
- if copy_ :
414
- if copy_ .access_type == 'public' :
415
- return True
416
- else :
417
- return False
418
- else :
419
- if __contains_noncopyable_mem_var ( class_ ):
420
- return False
421
- else :
422
- return True
423
- else :
424
- constructors = filter ( lambda x : isinstance ( x , calldef .constructor_t ) \
425
- and x .is_copy_constructor
426
- , class_ .public_members )
427
- return bool ( constructors )
428
-
429
- def has_destructor (type ):
430
- """returns True, if class has destructor, False otherwise"""
431
- assert isinstance ( type , class_declaration .class_t )
432
- return bool ( algorithm .find_declaration ( type .get_members ()
433
- , type = calldef .destructor_t
434
- , recursive = False ) )
435
-
436
- def has_public_constructor (type ):
437
- """returns True, if class has public constructor, False otherwise"""
438
- assert isinstance ( type , class_declaration .class_t )
439
- decls = algorithm .find_all_declarations ( type .public_members
440
- , type = calldef .constructor_t
441
- , recursive = False )
442
- constructors = filter ( lambda decl : not decl .is_copy_constructor , decls )
443
- return bool ( constructors ) or has_trivial_constructor ( type )
361
+ copy_constructor = class_ .find_copy_constructor ()
362
+ if copy_constructor and copy_constructor .access_type == 'public' :
363
+ return copy_constructor
444
364
445
- def has_public_assign (type ):
365
+ def has_destructor (class_ ):
366
+ """if class has destructor, this function will return reference to it, None otherwise"""
367
+ class_ = class_traits .get_declaration ( class_ )
368
+ destructor = class_ .decls ( decl_type = calldef .destructor_t , recursive = False , allow_empty = True )
369
+ if destructor :
370
+ return destructor [0 ]
371
+
372
+ def has_public_constructor (class_ ):
373
+ """if class has any public constructor, this function will return list of them, otherwise None"""
374
+ class_ = class_traits .get_declaration (class_ )
375
+ decls = class_ .constructors ( lambda c : not c .is_copy_constructor and c .access_type == 'public'
376
+ , recursive = False , allow_empty = True )
377
+ if decls :
378
+ return decls
379
+
380
+ def has_public_assign (class_ ):
446
381
"""returns True, if class has public assign operator, False otherwise"""
447
- assert isinstance ( type , class_declaration .class_t )
448
- decls = algorithm .find_all_declarations ( type .public_members
449
- , type = calldef .member_operator_t
450
- , recursive = False )
451
- decls = filter ( lambda decl : decl .symbol == '=' , decls )
382
+ class_ = class_traits .get_declaration ( class_ )
383
+ decls = class_ .mem_opers ( lambda o : o .symbol == '=' and o .access_type == 'public'
384
+ , recursive = False , allow_empty = True )
452
385
return bool ( decls )
453
386
454
387
def has_public_destructor (type ):
455
388
"""returns True, if class has public destructor, False otherwise"""
456
- assert isinstance ( type , class_declaration .class_t )
457
- return bool ( algorithm .find_declaration ( type .public_members
458
- , type = calldef .destructor_t
459
- , recursive = False ) )
389
+ d = has_destructor ( type )
390
+ return d and d .access_type == 'public'
460
391
461
392
def is_base_and_derived ( based , derived ):
462
393
"""returns True, if there is "base and derived" relationship between classes, False otherwise"""
@@ -468,20 +399,20 @@ def is_base_and_derived( based, derived ):
468
399
all_derived = ( [derived ] )
469
400
else : #tuple
470
401
all_derived = derived
471
-
402
+
472
403
for derived_cls in all_derived :
473
404
for base_desc in derived_cls .recursive_bases :
474
405
if base_desc .related_class == based :
475
406
return True
476
407
return False
477
-
408
+
478
409
def has_any_non_copyconstructor ( type ):
479
- """returns True, if class has any non " copy constructor", otherwise False """
480
- assert isinstance ( type , class_declaration . class_t )
481
- constructors = filter ( lambda x : isinstance ( x , calldef . constructor_t ) \
482
- and not x . is_copy_constructor
483
- , type . public_members )
484
- return bool ( constructors ) or has_trivial_constructor ( type )
410
+ """if class has any public constructor, which is not copy constructor, this function will return list of them, otherwise None """
411
+ class_ = class_traits . get_declaration ( type )
412
+ decls = class_ . constructors ( lambda c : not c . is_copy_constructor and c . access_type == 'public'
413
+ , recursive = False , allow_empty = True )
414
+ if decls :
415
+ return decls
485
416
486
417
def has_public_binary_operator ( type , operator_symbol ):
487
418
"""returns True, if type has public binary operator, otherwise False"""
@@ -916,36 +847,36 @@ def __is_noncopyable_single( class_):
916
847
if __contains_noncopyable_mem_var ( class_ ):
917
848
logger .debug ( "__is_noncopyable_single(TRUE) - %s - contains noncopyable members" % class_ .decl_string )
918
849
return True
919
- else :
850
+ else :
920
851
logger .debug ( "__is_noncopyable_single(FALSE) - %s - COPYABLE, because is doesn't contains noncopyable members" % class_ .decl_string )
921
852
return False
922
853
923
854
def is_noncopyable ( class_ ):
924
855
"""returns True, if class is noncopyable, False otherwise"""
925
- logger = utils .loggers .cxx_parser
856
+ logger = utils .loggers .cxx_parser
926
857
class_ = class_traits .get_declaration ( class_ )
927
-
858
+
928
859
true_header = "is_noncopyable(TRUE) - %s - " % class_ .decl_string
929
860
false_header = "is_noncopyable(false) - %s - " % class_ .decl_string
930
-
861
+
931
862
if class_ .class_type == class_declaration .CLASS_TYPES .UNION :
932
863
return False
933
864
934
865
if class_ .is_abstract :
935
866
logger .debug ( true_header + "abstract client" )
936
867
return True
937
868
938
- #if class has public, user defined copy constructor, than this class is
869
+ #if class has public, user defined copy constructor, than this class is
939
870
#copyable
940
871
copy_ = class_ .find_copy_constructor ()
941
872
if copy_ and copy_ .access_type == 'public' and not copy_ .is_artificial :
942
873
return False
943
-
874
+
944
875
for base_desc in class_ .recursive_bases :
945
- assert isinstance ( base_desc , class_declaration .hierarchy_info_t )
876
+ assert isinstance ( base_desc , class_declaration .hierarchy_info_t )
946
877
if base_desc .related_class .decl_string in ('::boost::noncopyable' , '::boost::noncopyable_::noncopyable' ):
947
878
logger .debug ( true_header + "derives from boost::noncopyable" )
948
- return True
879
+ return True
949
880
if not has_copy_constructor ( base_desc .related_class ):
950
881
base_copy_ = base_desc .related_class .find_copy_constructor ()
951
882
if base_copy_ :
@@ -959,7 +890,7 @@ def is_noncopyable( class_ ):
959
890
if __is_noncopyable_single ( base_desc .related_class ):
960
891
logger .debug ( true_header + "__is_noncopyable_single returned True" )
961
892
return True
962
-
893
+
963
894
if not has_copy_constructor ( class_ ):
964
895
logger .debug ( true_header + "does not have trival copy constructor" )
965
896
return True
@@ -1032,9 +963,9 @@ def find_value_type( global_ns, value_type_str ):
1032
963
found = global_ns .decls ( name = value_type_str
1033
964
, function = lambda decl : not isinstance ( decl , calldef .calldef_t )
1034
965
, allow_empty = True )
1035
- if not found :
966
+ if not found :
1036
967
no_global_ns_value_type_str = value_type_str [2 :]
1037
- if cpptypes .FUNDAMENTAL_TYPES .has_key ( no_global_ns_value_type_str ):
968
+ if cpptypes .FUNDAMENTAL_TYPES .has_key ( no_global_ns_value_type_str ):
1038
969
return cpptypes .FUNDAMENTAL_TYPES [ no_global_ns_value_type_str ]
1039
970
elif is_std_string ( value_type_str ):
1040
971
string_ = global_ns .typedef ( '::std::string' )
@@ -1137,7 +1068,7 @@ def is_std_ostream( type ):
1137
1068
else :
1138
1069
type = remove_alias ( type )
1139
1070
return remove_cv ( type ).decl_string in decl_strings
1140
-
1071
+
1141
1072
1142
1073
def is_std_wostream ( type ):
1143
1074
"""returns True, if type represents C++ std::string, False otherwise"""
0 commit comments