* @brief The first type must be TK_UNION. * The second type must not be TK_ALIAS. */
| 670 | * The second type must not be TK_ALIAS. |
| 671 | */ |
| 672 | bool TypeAssignability::assignable_union(const MinimalTypeObject& ta, |
| 673 | const MinimalTypeObject& tb) const |
| 674 | { |
| 675 | if (TK_UNION != tb.kind) { |
| 676 | return false; |
| 677 | } |
| 678 | |
| 679 | // Extensibility kind must match |
| 680 | const TypeFlag extensibility_mask = IS_FINAL | IS_APPENDABLE | IS_MUTABLE; |
| 681 | if ((ta.union_type.union_flags & extensibility_mask) != |
| 682 | (tb.union_type.union_flags & extensibility_mask)) { |
| 683 | return false; |
| 684 | } |
| 685 | |
| 686 | OPENDDS_SET(ACE_CDR::Long) labels_set_a; |
| 687 | for (unsigned i = 0; i < ta.union_type.member_seq.length(); ++i) { |
| 688 | const UnionCaseLabelSeq& labels_a = ta.union_type.member_seq[i].common.label_seq; |
| 689 | labels_set_a.insert(labels_a.members.begin(), labels_a.members.end()); |
| 690 | } |
| 691 | |
| 692 | // If extensibility is final, then the set of labels must be identical. |
| 693 | // Assuming labels are mapped to values identically in both input types. |
| 694 | if ((ta.union_type.union_flags & extensibility_mask) == IS_FINAL) { |
| 695 | for (unsigned i = 0; i < tb.union_type.member_seq.length(); ++i) { |
| 696 | const UnionCaseLabelSeq& labels_b = tb.union_type.member_seq[i].common.label_seq; |
| 697 | for (unsigned j = 0; j < labels_b.length(); ++j) { |
| 698 | if (labels_set_a.find(labels_b.members[j]) == labels_set_a.end()) { |
| 699 | return false; |
| 700 | } |
| 701 | labels_set_a.erase(labels_b.members[j]); |
| 702 | } |
| 703 | } |
| 704 | if (labels_set_a.size() > 0) { |
| 705 | return false; |
| 706 | } |
| 707 | } else { // Must have at least one common label other than the default |
| 708 | // This implementation assumes that the default member has IS_DEFAULT |
| 709 | // flag turned on, but the label "default" does not map into a numeric |
| 710 | // value for storing on the member's UnionCaseLabelSeq. Instead, only |
| 711 | // the other labels, if any, for this default members will have their |
| 712 | // numeric values stored in its UnionCaseLabelSeq. |
| 713 | bool found = false; |
| 714 | for (unsigned i = 0; i < tb.union_type.member_seq.length(); ++i) { |
| 715 | const UnionCaseLabelSeq& labels_b = tb.union_type.member_seq[i].common.label_seq; |
| 716 | for (unsigned j = 0; j < labels_b.length(); ++j) { |
| 717 | if (labels_set_a.find(labels_b[j]) != labels_set_a.end()) { |
| 718 | found = true; |
| 719 | break; |
| 720 | } |
| 721 | } |
| 722 | if (found) break; |
| 723 | } |
| 724 | if (!found) { |
| 725 | return false; |
| 726 | } |
| 727 | } |
| 728 | |
| 729 | // Discriminator type must be one of these: (i) non-float primitive types, |