docs: def is_noncopyable(class_, already_visited_cls_vars=None):
      """
      Checks if class is non copyable
  
      Args:
          class_ (declarations.class_t): the class to be checked
          already_visited_cls_vars (list): optional list of vars that should not
              be checked a second time, to prevent infinite recursions.
              In general you can ignore this argument, it is mainly used during
              recursive calls of is_noncopyable() done by pygccxml.
  
      Returns:
          bool: if the class is non copyable
      """
      logger = utils.loggers.cxx_parser
  
      class_decl = class_traits.get_declaration(class_)
  
      true_header = "is_noncopyable(TRUE) - %s - " % class_.decl_string
  
      if is_union(class_):
          return False
  
      if class_decl.is_abstract:
          logger.debug(true_header + "abstract client")
          return True
  
      # if class has public, user defined copy constructor, than this class is
      # copyable
      copy_ = find_copy_constructor(class_decl)
      if copy_ and copy_.access_type == 'public' and not copy_.is_artificial:
          return False
  
      if already_visited_cls_vars is None:
          already_visited_cls_vars = []
  
      for base_desc in class_decl.recursive_bases:
          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
  
          if not has_copy_constructor(base_desc.related_class):
  
              base_copy_ = find_copy_constructor(base_desc.related_class)
  
              if base_copy_ and base_copy_.access_type == 'private':
                  logger.debug(
                      true_header +
                      "there is private copy constructor")
                  return True
              elif __is_noncopyable_single(
                      base_desc.related_class, already_visited_cls_vars):
                  logger.debug(
                      true_header +
                      "__is_noncopyable_single returned True")
                  return True
  
          if __is_noncopyable_single(
                  base_desc.related_class, already_visited_cls_vars):
              logger.debug(
                  true_header +
                  "__is_noncopyable_single returned True")
              return True
  
      if not has_copy_constructor(class_decl):
          logger.debug(true_header + "does not have trivial copy constructor")
          return True
      elif not has_public_constructor(class_decl):
          logger.debug(true_header + "does not have a public constructor")
          return True
      elif has_destructor(class_decl) and not has_public_destructor(class_decl):
          logger.debug(true_header + "has private destructor")
          return True
  
      return __is_noncopyable_single(class_decl, already_visited_cls_vars)