* @brief The first type must be TK_ENUM. * The second type must not be TK_ALIAS. */
| 1077 | * The second type must not be TK_ALIAS. |
| 1078 | */ |
| 1079 | bool TypeAssignability::assignable_enum(const MinimalTypeObject& ta, |
| 1080 | const MinimalTypeObject& tb) const |
| 1081 | { |
| 1082 | if (TK_ENUM != tb.kind) { |
| 1083 | return false; |
| 1084 | } |
| 1085 | |
| 1086 | // Assuming that EnumTypeFlag is used and contains extensibility |
| 1087 | // of the containing type. |
| 1088 | const TypeFlag extensibility_mask = IS_FINAL | IS_APPENDABLE | IS_MUTABLE; |
| 1089 | TypeFlag ta_ext = ta.enumerated_type.enum_flags & extensibility_mask; |
| 1090 | TypeFlag tb_ext = tb.enumerated_type.enum_flags & extensibility_mask; |
| 1091 | if (ta_ext != tb_ext && |
| 1092 | // Backwards compatibility. |
| 1093 | ta_ext != 0 && tb_ext != 0) { |
| 1094 | return false; |
| 1095 | } |
| 1096 | |
| 1097 | // T1.bit_bound and T2.bit_bound must be equal (DDSXTY14-34) |
| 1098 | if (ta.enumerated_type.header.common.bit_bound != |
| 1099 | tb.enumerated_type.header.common.bit_bound) { |
| 1100 | return false; |
| 1101 | } |
| 1102 | |
| 1103 | const size_t size_a = ta.enumerated_type.literal_seq.members.size(); |
| 1104 | const size_t size_b = tb.enumerated_type.literal_seq.members.size(); |
| 1105 | OPENDDS_MAP(ACE_CDR::ULong, ACE_CDR::Long) ta_name_to_value; |
| 1106 | for (size_t i = 0; i < size_a; ++i) { |
| 1107 | const ACE_CDR::ULong key_a = to_uint(ta.enumerated_type.literal_seq.members[i].detail.name_hash); |
| 1108 | ta_name_to_value[key_a] = ta.enumerated_type.literal_seq.members[i].common.value; |
| 1109 | } |
| 1110 | |
| 1111 | // If extensibility is FINAL, both must have the same literals. |
| 1112 | if (IS_FINAL == ta_ext) { |
| 1113 | if (size_a != size_b) { |
| 1114 | return false; |
| 1115 | } |
| 1116 | |
| 1117 | for (size_t i = 0; i < size_b; ++i) { |
| 1118 | const ACE_CDR::ULong key_b = to_uint(tb.enumerated_type.literal_seq.members[i].detail.name_hash); |
| 1119 | |
| 1120 | // Literals that have the same name must have the same value. |
| 1121 | if (ta_name_to_value.find(key_b) == ta_name_to_value.end() || |
| 1122 | ta_name_to_value[key_b] != tb.enumerated_type.literal_seq.members[i].common.value) { |
| 1123 | return false; |
| 1124 | } |
| 1125 | } |
| 1126 | } else { |
| 1127 | // Any literals that have the same name also have the same value |
| 1128 | for (size_t i = 0; i < size_b; ++i) { |
| 1129 | const ACE_CDR::ULong key_b = to_uint(tb.enumerated_type.literal_seq.members[i].detail.name_hash); |
| 1130 | if (ta_name_to_value.find(key_b) != ta_name_to_value.end() && |
| 1131 | ta_name_to_value[key_b] != tb.enumerated_type.literal_seq.members[i].common.value) { |
| 1132 | return false; |
| 1133 | } |
| 1134 | } |
| 1135 | |
| 1136 | OPENDDS_MAP(ACE_CDR::Long, ACE_CDR::ULong) ta_value_to_name; |