Package pygccxml :: Package declarations :: Module function_traits |

# Source Code for Module pygccxml.declarations.function_traits

     1  # Copyright 2004-2008 Roman Yakovenko.
     2  # Distributed under the Boost Software License, Version 1.0. (See
     3  # accompanying file LICENSE_1_0.txt or copy at
     4  # http://www.boost.org/LICENSE_1_0.txt)
     5
     6  """
     7  defines few algorithms, that deals with different properties of functions
     8  """
     9
    10  import calldef
    11  import type_traits
    12  import class_declaration
    13
    14 -def is_same_return_type( f1, f2 ):
    15      #covariant returns
    16      #The return type of an overriding function shall be either identical to the
    17      #return type of the overridden function or covariant with the classes of the
    18      #functions. If a function D::f overrides a function B::f, the return types
    19      #of the functions are covariant if they satisfy the following criteria:
    20
    21      #* both are pointers to classes or references to classes
    22      #* the class in the return type of B::f is the same class as the class in
    23      #  the return type of D::f or, is an unambiguous direct or indirect base
    24      #  class of the class in the return type of D::f and is accessible in D
    25      #* both pointers or references have the same cv-qualification and the class
    26      #  type in the return type of D::f has the same cv-qualification as or less
    27      #  cv-qualification than the class type in the return type of B::f.
    28
    29      if not f1.__class__ is f2.__class__:
    30          #it should be assert
    31          return False #2 different calldef types
    32      if not isinstance( f1, calldef.member_calldef_t ):
    33          #for free functions we compare return types as usual
    34          return type_traits.is_same( f1.return_type, f2.return_type)
    35      if f1.virtuality == calldef.VIRTUALITY_TYPES.NOT_VIRTUAL \
    36         or f2.virtuality == calldef.VIRTUALITY_TYPES.NOT_VIRTUAL:
    37          #for non-virtual member functions we compare types as usual
    38          return type_traits.is_same( f1.return_type, f2.return_type)
    39      rt1 = f1.return_type
    40      rt2 = f2.return_type
    41      if type_traits.is_pointer( rt1 ) and type_traits.is_pointer( rt2 ):
    42          rt1 = type_traits.remove_pointer( rt1 )
    43          rt2 = type_traits.remove_pointer( rt2 )
    44      elif type_traits.is_reference( rt1 ) and type_traits.is_reference( rt2 ):
    45          rt1 = type_traits.remove_reference( rt1 )
    46          rt2 = type_traits.remove_reference( rt2 )
    47      else:
    48          return type_traits.is_same( f1.return_type, f2.return_type)
    49      if ( type_traits.is_const( rt1 ) and type_traits.is_const( rt2 ) ) \
    50         or ( False == type_traits.is_const( rt1 ) and False == type_traits.is_const( rt2 ) ):
    51          rt1 = type_traits.remove_const( rt1 )
    52          rt2 = type_traits.remove_const( rt2 )
    53      else:
    54          return False
    55      if not type_traits.is_class( rt1 ) or not type_traits.is_class( rt2 ):
    56          return type_traits.is_same( rt1, rt2 )
    57      c1 = type_traits.class_traits.get_declaration( rt1 )
    58      c2 = type_traits.class_traits.get_declaration( rt2 )
    59      if c1.class_type == class_declaration.CLASS_TYPES.UNION \
    60         or c2.class_type == class_declaration.CLASS_TYPES.UNION:
    61          return type_traits.is_same( rt1, rt2 )
    62      return type_traits.is_same( c1, c2 ) \
    63             or type_traits.is_base_and_derived( c1, c2 ) \
    64             or type_traits.is_base_and_derived( c2, c1 )
    65
    66
    67 -def is_same_function( f1, f2 ):
    68      """returns true if f1 and f2 is same function
    69
    70      Use case: sometimes when user defines some virtual function in base class,
    71      it overrides it in a derived one. Sometimes we need to know whether two member
    72      functions is actualy same function.
    73      """
    74      if f1 is f2:
    75          return True
    76      if not f1.__class__ is f2.__class__:
    77          return False
    78      if isinstance( f1, calldef.member_calldef_t ) and f1.has_const != f2.has_const:
    79          return False
    80      if f1.name != f2.name:
    81          return False
    82      if not is_same_return_type( f1, f2 ):
    83          return False
    84      if len( f1.arguments ) != len(f2.arguments):
    85          return False
    86      for f1_arg, f2_arg in zip( f1.arguments, f2.arguments ):
    87          if not type_traits.is_same( f1_arg.type, f2_arg.type ):
    88              return False
    89      return True
    90