code: def process_member_definitions(cls, member_definitions):
          
          members = []
          auto_flags = []
          all_bits = 0
          for name, data in member_definitions:
              bits, data = cls.flag_attribute_value_to_bits_and_data(name, data)
              if bits is UNDEFINED:
                  auto_flags.append(len(members))
                  members.append((name, data))
              elif is_valid_bits_value(bits):
                  all_bits |= bits
                  members.append((name, bits, data))
              else:
                  raise TypeError("Expected an int value as the bits of flag '%s', received %r" % (name, bits))
  
          # auto-assigning unused bits to members without custom defined bits
          bit = 1
          for index in auto_flags:
              while bit & all_bits:
                  bit <<= 1
              name, data = members[index]
              members[index] = name, bit, data
              bit <<= 1
  
          return members
docs: The incoming member_definitions contains the class attributes (with their values) that are
          used to define the flag members. This method can do anything to the incoming list and has to
          return a final set of flag definitions that assigns bits to the members. The returned member
          definitions can be completely different or unrelated to the incoming ones.
          :param member_definitions: A list of (name, data) tuples.
          :return: An iterable of iterables yielding 3 items: name, bits, data