OpenDDS  Snapshot(2023/04/28-20:55)
Public Member Functions | Private Member Functions | Private Attributes | List of all members
OpenDDS::XTypes::TypeAssignability Class Reference

#include <TypeAssignability.h>

Collaboration diagram for OpenDDS::XTypes::TypeAssignability:
Collaboration graph
[legend]

Public Member Functions

 TypeAssignability (TypeLookupService_rch tls)
 
 TypeAssignability (TypeLookupService_rch tls, TypeConsistencyAttributes type_consistency)
 
bool assignable (const TypeObject &ta, const TypeObject &tb) const
 Both input type objects must be minimal. More...
 
bool assignable (const TypeObject &ta, const TypeIdentifier &tb) const
 The first argument must be a minimal type object. More...
 
bool assignable (const TypeIdentifier &ta, const TypeIdentifier &tb) const
 Both input can be of any type. More...
 
bool assignable (const TypeIdentifier &ta, const TypeObject &tb) const
 The second argument must be a minimal type object. More...
 
void set_prevent_type_widening (bool value)
 
void set_ignore_sequence_bounds (bool value)
 
void set_ignore_string_bounds (bool value)
 
void set_ignore_member_names (bool value)
 
void insert_entry (const TypeIdentifier &ti, const TypeObject &tobj)
 

Private Member Functions

bool assignable_alias (const MinimalTypeObject &ta, const MinimalTypeObject &tb) const
 At least one input type object must be TK_ALIAS. More...
 
bool assignable_annotation (const MinimalTypeObject &ta, const MinimalTypeObject &tb) const
 The first type must be TK_ANNOTATION. The second type must not be TK_ALIAS. More...
 
bool assignable_annotation (const MinimalTypeObject &ta, const TypeIdentifier &tb) const
 The first type must be TK_ANNOTATION. The second type can be anything. More...
 
bool assignable_struct (const MinimalTypeObject &ta, const MinimalTypeObject &tb) const
 The first type must be TK_STRUCTURE. The second type must not be TK_ALIAS. More...
 
bool assignable_struct (const MinimalTypeObject &ta, const TypeIdentifier &tb) const
 The first type must be TK_STRUCTURE. The second type can be anything. More...
 
bool assignable_union (const MinimalTypeObject &ta, const MinimalTypeObject &tb) const
 The first type must be TK_UNION. The second type must not be TK_ALIAS. More...
 
bool assignable_union (const MinimalTypeObject &ta, const TypeIdentifier &tb) const
 The first type must be TK_UNION. The second type can be anything. More...
 
bool assignable_bitset (const MinimalTypeObject &ta, const MinimalTypeObject &tb) const
 The first type must be TK_BITSET. The second type must not be TK_ALIAS. More...
 
bool assignable_bitset (const MinimalTypeObject &ta, const TypeIdentifier &tb) const
 The first type must be TK_BITSET. The second type can be anything. More...
 
bool assignable_sequence (const MinimalTypeObject &ta, const MinimalTypeObject &tb) const
 The first type must be TK_SEQUENCE. The second type must not be TK_ALIAS. More...
 
bool assignable_sequence (const MinimalTypeObject &ta, const TypeIdentifier &tb) const
 The first type must be TK_SEQUENCE. The second type can be anything. More...
 
bool assignable_array (const MinimalTypeObject &ta, const MinimalTypeObject &tb) const
 The first type must be TK_ARRAY. The second type must not be TK_ALIAS. More...
 
bool assignable_array (const MinimalTypeObject &ta, const TypeIdentifier &tb) const
 The first type must be TK_ARRAY. The second type can be anything. More...
 
bool assignable_map (const MinimalTypeObject &ta, const MinimalTypeObject &tb) const
 The first type must be TK_MAP. The second type must not be TK_ALIAS. More...
 
bool assignable_map (const MinimalTypeObject &ta, const TypeIdentifier &tb) const
 The first type must be TK_MAP. The second type can be anything. More...
 
bool assignable_enum (const MinimalTypeObject &ta, const MinimalTypeObject &tb) const
 The first type must be TK_ENUM. The second type must not be TK_ALIAS. More...
 
bool assignable_enum (const MinimalTypeObject &ta, const TypeIdentifier &tb) const
 The first type must be TK_ENUM. The second type can be anything. More...
 
bool assignable_bitmask (const MinimalTypeObject &ta, const MinimalTypeObject &tb) const
 The first type must be TK_BITMASK. The second type must not be TK_ALIAS. More...
 
bool assignable_bitmask (const MinimalTypeObject &ta, const TypeIdentifier &tb) const
 The first type must be TK_BITMASK. The second type can be anything. More...
 
bool assignable_extended (const MinimalTypeObject &ta, const MinimalTypeObject &tb) const
 The first type must be a future extension type kind. The second type must not be TK_ALIAS. More...
 
bool assignable_primitive (const TypeIdentifier &ta, const TypeIdentifier &tb) const
 The first type must be a primitive type. The second type can be anything. More...
 
bool assignable_primitive (const TypeIdentifier &ta, const MinimalTypeObject &tb) const
 The first type must be a primitive type. The second type must not be TK_ALIAS. More...
 
bool assignable_string (const TypeIdentifier &ta, const TypeIdentifier &tb) const
 The first type must be a string type. The second type can be anything. More...
 
bool assignable_string (const TypeIdentifier &ta, const MinimalTypeObject &tb) const
 The first type must be a string type. The second type must not be TK_ALIAS. More...
 
bool assignable_plain_sequence (const TypeIdentifier &ta, const TypeIdentifier &tb) const
 The first type must be a plain sequence type. The second type can be anything. More...
 
bool assignable_plain_sequence (const TypeIdentifier &ta, const MinimalTypeObject &tb) const
 The first type must be a plain sequence type. The second type must not be TK_ALIAS. More...
 
bool assignable_plain_array (const TypeIdentifier &ta, const TypeIdentifier &tb) const
 The first type must be a plain array type. The second type can be anything. More...
 
bool assignable_plain_array (const TypeIdentifier &ta, const MinimalTypeObject &tb) const
 The first type must be a plain array type. The second type must not be TK_ALIAS. More...
 
bool assignable_plain_map (const TypeIdentifier &ta, const TypeIdentifier &tb) const
 The first type must be a plain map type. The second type can be anything. More...
 
bool assignable_plain_map (const TypeIdentifier &ta, const MinimalTypeObject &tb) const
 The first type must be a plain map type. The second type must not be TK_ALIAS. More...
 
bool strongly_assignable (const TypeIdentifier &ta, const TypeIdentifier &tb) const
 If types T1 and T2 are equivalent using the MINIMAL relation, or alternatively if T1 is-assignable-from T2 and T2 is a delimited type, then T1 is said to be strongly assignable from T2. More...
 
bool is_delimited (const TypeIdentifier &ti) const
 Concept of delimited types (sub-clause 7.2.4.2) More...
 
bool is_delimited (const MinimalTypeObject &tobj) const
 Check if a type is delimited (sub-clause 7.2.4.2) More...
 
bool is_delimited_with_flags (TypeFlag flags) const
 
bool equal_type_id (const TypeIdentifier &tia, const TypeIdentifier &tib) const
 Check whether two type identifiers are equal. More...
 
const TypeIdentifierget_base_type (const MinimalTypeObject &type) const
 The input must be of type TK_ALIAS Return the non-alias base type identifier of the input. More...
 
void erase_key (MinimalTypeObject &type) const
 Key-Erased type of an aggregated type T (struct or union) is constructed from T by removing the key designation from any member that has it (sub-clause 7.2.2.4.6). The input type must be either a struct or an union. More...
 
void hold_key (MinimalTypeObject &type) const
 Key-Holder type of an aggregated type T (struct or union) is constructed from T (sub-clause 7.2.2.4.7) The input MinimalTypeObject is modified to get the corresponding KeyHolder type. The input must be either a struct or an union. More...
 
bool hold_key (const TypeIdentifier &ti, MinimalTypeObject &to) const
 Return false if the input type does not have type object; the output MinimalTypeObject is not used in this case. Return true if the input type has type object; the output MinimalTypeObject contains the KeyHolder type of the corresponding type. More...
 
bool struct_rule_enum_key (const MinimalTypeObject &tb, const CommonStructMember &ma) const
 The first argument must be TK_ENUM and is the type object of a key member of the containing struct. Therefore, there must be a member with the same ID (and name) in the other struct type. More...
 
bool get_sequence_bound (LBound &b, const CommonStructMember &m) const
 Check whether a struct member is of sequence type and if so compute its bound into the first argument. More...
 
bool get_map_bound (LBound &b, const CommonStructMember &m) const
 Check whether a struct member is of map type and if so compute its bound into the first argument. More...
 
bool get_string_bound (LBound &b, const CommonStructMember &m) const
 Check whether the input struct member is of string type and if so compute its bound into the first argument. More...
 
bool get_struct_member (const MinimalTypeObject *&ret, const CommonStructMember &m) const
 Check if the second argument is of a struct type and if so return its type object as the first argument. More...
 
bool get_union_member (const MinimalTypeObject *&ret, const CommonStructMember &m) const
 Check if the second argument is of a union type and if so return its type object as the first argument. More...
 
const MinimalTypeObjectlookup_minimal (const TypeIdentifier &ti) const
 

Private Attributes

XTypes::TypeLookupService_rch tl_service_
 
TypeConsistencyAttributes type_consistency_
 

Detailed Description

Definition at line 35 of file TypeAssignability.h.

Constructor & Destructor Documentation

◆ TypeAssignability() [1/2]

OpenDDS::XTypes::TypeAssignability::TypeAssignability ( TypeLookupService_rch  tls)
inlineexplicit

◆ TypeAssignability() [2/2]

OpenDDS::XTypes::TypeAssignability::TypeAssignability ( TypeLookupService_rch  tls,
TypeConsistencyAttributes  type_consistency 
)
inline

Definition at line 47 of file TypeAssignability.h.

49  : tl_service_(tls)
50  , type_consistency_(type_consistency) {}
XTypes::TypeLookupService_rch tl_service_
TypeConsistencyAttributes type_consistency_

Member Function Documentation

◆ assignable() [1/4]

bool OpenDDS::XTypes::TypeAssignability::assignable ( const TypeObject ta,
const TypeObject tb 
) const

Both input type objects must be minimal.

Definition at line 19 of file TypeAssignability.cpp.

References assignable_alias(), assignable_annotation(), assignable_array(), assignable_bitmask(), assignable_bitset(), assignable_enum(), assignable_extended(), assignable_map(), assignable_sequence(), assignable_struct(), assignable_union(), OpenDDS::XTypes::EK_MINIMAL, OpenDDS::XTypes::MinimalTypeObject::kind, OpenDDS::XTypes::TypeObject::kind, OpenDDS::XTypes::TypeObject::minimal, OpenDDS::XTypes::TK_ALIAS, OpenDDS::XTypes::TK_ANNOTATION, OpenDDS::XTypes::TK_ARRAY, OpenDDS::XTypes::TK_BITMASK, OpenDDS::XTypes::TK_BITSET, OpenDDS::XTypes::TK_ENUM, OpenDDS::XTypes::TK_MAP, OpenDDS::XTypes::TK_SEQUENCE, OpenDDS::XTypes::TK_STRUCTURE, and OpenDDS::XTypes::TK_UNION.

Referenced by assignable(), assignable_alias(), assignable_struct(), assignable_union(), OpenDDS::DCPS::StaticEndpointManager::match_continue(), OpenDDS::RTPS::Sedp::match_continue(), and strongly_assignable().

21 {
22  if (EK_MINIMAL == ta.kind && EK_MINIMAL == tb.kind) {
23  if (TK_ALIAS == ta.minimal.kind || TK_ALIAS == tb.minimal.kind) {
24  return assignable_alias(ta.minimal, tb.minimal);
25  }
26 
27  switch (ta.minimal.kind) {
28  case TK_ANNOTATION:
29  return assignable_annotation(ta.minimal, tb.minimal);
30  case TK_STRUCTURE:
31  return assignable_struct(ta.minimal, tb.minimal);
32  case TK_UNION:
33  return assignable_union(ta.minimal, tb.minimal);
34  case TK_BITSET:
35  return assignable_bitset(ta.minimal, tb.minimal);
36  case TK_SEQUENCE:
37  return assignable_sequence(ta.minimal, tb.minimal);
38  case TK_ARRAY:
39  return assignable_array(ta.minimal, tb.minimal);
40  case TK_MAP:
41  return assignable_map(ta.minimal, tb.minimal);
42  case TK_ENUM:
43  return assignable_enum(ta.minimal, tb.minimal);
44  case TK_BITMASK:
45  return assignable_bitmask(ta.minimal, tb.minimal);
46  default:
47  return assignable_extended(ta.minimal, tb.minimal);
48  }
49  }
50 
51  return false;
52 }
bool assignable_extended(const MinimalTypeObject &ta, const MinimalTypeObject &tb) const
The first type must be a future extension type kind. The second type must not be TK_ALIAS.
const TypeKind TK_SEQUENCE
Definition: TypeObject.h:248
const TypeKind TK_UNION
Definition: TypeObject.h:244
bool assignable_enum(const MinimalTypeObject &ta, const MinimalTypeObject &tb) const
The first type must be TK_ENUM. The second type must not be TK_ALIAS.
bool assignable_struct(const MinimalTypeObject &ta, const MinimalTypeObject &tb) const
The first type must be TK_STRUCTURE. The second type must not be TK_ALIAS.
bool assignable_array(const MinimalTypeObject &ta, const MinimalTypeObject &tb) const
The first type must be TK_ARRAY. The second type must not be TK_ALIAS.
bool assignable_annotation(const MinimalTypeObject &ta, const MinimalTypeObject &tb) const
The first type must be TK_ANNOTATION. The second type must not be TK_ALIAS.
const TypeKind TK_BITMASK
Definition: TypeObject.h:239
bool assignable_sequence(const MinimalTypeObject &ta, const MinimalTypeObject &tb) const
The first type must be TK_SEQUENCE. The second type must not be TK_ALIAS.
bool assignable_union(const MinimalTypeObject &ta, const MinimalTypeObject &tb) const
The first type must be TK_UNION. The second type must not be TK_ALIAS.
const TypeKind TK_STRUCTURE
Definition: TypeObject.h:243
const TypeKind TK_ALIAS
Definition: TypeObject.h:235
const TypeKind TK_ANNOTATION
Definition: TypeObject.h:242
const TypeKind TK_ENUM
Definition: TypeObject.h:238
bool assignable_alias(const MinimalTypeObject &ta, const MinimalTypeObject &tb) const
At least one input type object must be TK_ALIAS.
const EquivalenceKind EK_MINIMAL
Definition: TypeObject.h:205
bool assignable_bitmask(const MinimalTypeObject &ta, const MinimalTypeObject &tb) const
The first type must be TK_BITMASK. The second type must not be TK_ALIAS.
const TypeKind TK_ARRAY
Definition: TypeObject.h:249
bool assignable_map(const MinimalTypeObject &ta, const MinimalTypeObject &tb) const
The first type must be TK_MAP. The second type must not be TK_ALIAS.
const TypeKind TK_MAP
Definition: TypeObject.h:250
bool assignable_bitset(const MinimalTypeObject &ta, const MinimalTypeObject &tb) const
The first type must be TK_BITSET. The second type must not be TK_ALIAS.
const TypeKind TK_BITSET
Definition: TypeObject.h:245

◆ assignable() [2/4]

bool OpenDDS::XTypes::TypeAssignability::assignable ( const TypeObject ta,
const TypeIdentifier tb 
) const

The first argument must be a minimal type object.

Definition at line 57 of file TypeAssignability.cpp.

References assignable(), assignable_annotation(), assignable_array(), assignable_bitmask(), assignable_bitset(), assignable_enum(), assignable_map(), assignable_sequence(), assignable_struct(), assignable_union(), OpenDDS::XTypes::EK_MINIMAL, get_base_type(), OpenDDS::XTypes::MinimalTypeObject::kind, OpenDDS::XTypes::TypeObject::kind, OpenDDS::XTypes::TypeObject::minimal, OpenDDS::XTypes::TK_ALIAS, OpenDDS::XTypes::TK_ANNOTATION, OpenDDS::XTypes::TK_ARRAY, OpenDDS::XTypes::TK_BITMASK, OpenDDS::XTypes::TK_BITSET, OpenDDS::XTypes::TK_ENUM, OpenDDS::XTypes::TK_MAP, OpenDDS::XTypes::TK_SEQUENCE, OpenDDS::XTypes::TK_STRUCTURE, and OpenDDS::XTypes::TK_UNION.

59 {
60  if (EK_MINIMAL == ta.kind) {
61  if (TK_ALIAS == ta.minimal.kind) {
62  return assignable(get_base_type(ta.minimal), tb);
63  }
64 
65  switch (ta.minimal.kind) {
66  case TK_ANNOTATION:
67  return assignable_annotation(ta.minimal, tb);
68  case TK_STRUCTURE:
69  return assignable_struct(ta.minimal, tb);
70  case TK_UNION:
71  return assignable_union(ta.minimal, tb);
72  case TK_BITSET:
73  return assignable_bitset(ta.minimal, tb);
74  case TK_SEQUENCE:
75  return assignable_sequence(ta.minimal, tb);
76  case TK_ARRAY:
77  return assignable_array(ta.minimal, tb);
78  case TK_MAP:
79  return assignable_map(ta.minimal, tb);
80  case TK_ENUM:
81  return assignable_enum(ta.minimal, tb);
82  case TK_BITMASK:
83  return assignable_bitmask(ta.minimal, tb);
84  default:
85  return false;
86  }
87  }
88 
89  return false;
90 }
const TypeKind TK_SEQUENCE
Definition: TypeObject.h:248
const TypeKind TK_UNION
Definition: TypeObject.h:244
bool assignable_enum(const MinimalTypeObject &ta, const MinimalTypeObject &tb) const
The first type must be TK_ENUM. The second type must not be TK_ALIAS.
bool assignable_struct(const MinimalTypeObject &ta, const MinimalTypeObject &tb) const
The first type must be TK_STRUCTURE. The second type must not be TK_ALIAS.
const TypeIdentifier & get_base_type(const MinimalTypeObject &type) const
The input must be of type TK_ALIAS Return the non-alias base type identifier of the input...
bool assignable_array(const MinimalTypeObject &ta, const MinimalTypeObject &tb) const
The first type must be TK_ARRAY. The second type must not be TK_ALIAS.
bool assignable_annotation(const MinimalTypeObject &ta, const MinimalTypeObject &tb) const
The first type must be TK_ANNOTATION. The second type must not be TK_ALIAS.
const TypeKind TK_BITMASK
Definition: TypeObject.h:239
bool assignable_sequence(const MinimalTypeObject &ta, const MinimalTypeObject &tb) const
The first type must be TK_SEQUENCE. The second type must not be TK_ALIAS.
bool assignable_union(const MinimalTypeObject &ta, const MinimalTypeObject &tb) const
The first type must be TK_UNION. The second type must not be TK_ALIAS.
const TypeKind TK_STRUCTURE
Definition: TypeObject.h:243
bool assignable(const TypeObject &ta, const TypeObject &tb) const
Both input type objects must be minimal.
const TypeKind TK_ALIAS
Definition: TypeObject.h:235
const TypeKind TK_ANNOTATION
Definition: TypeObject.h:242
const TypeKind TK_ENUM
Definition: TypeObject.h:238
const EquivalenceKind EK_MINIMAL
Definition: TypeObject.h:205
bool assignable_bitmask(const MinimalTypeObject &ta, const MinimalTypeObject &tb) const
The first type must be TK_BITMASK. The second type must not be TK_ALIAS.
const TypeKind TK_ARRAY
Definition: TypeObject.h:249
bool assignable_map(const MinimalTypeObject &ta, const MinimalTypeObject &tb) const
The first type must be TK_MAP. The second type must not be TK_ALIAS.
const TypeKind TK_MAP
Definition: TypeObject.h:250
bool assignable_bitset(const MinimalTypeObject &ta, const MinimalTypeObject &tb) const
The first type must be TK_BITSET. The second type must not be TK_ALIAS.
const TypeKind TK_BITSET
Definition: TypeObject.h:245

◆ assignable() [3/4]

bool OpenDDS::XTypes::TypeAssignability::assignable ( const TypeIdentifier ta,
const TypeIdentifier tb 
) const

Both input can be of any type.

Definition at line 95 of file TypeAssignability.cpp.

References assignable(), assignable_plain_array(), assignable_plain_map(), assignable_plain_sequence(), assignable_primitive(), assignable_string(), OpenDDS::XTypes::EK_COMPLETE, OpenDDS::XTypes::EK_MINIMAL, OpenDDS::XTypes::TypeIdentifier::kind(), lookup_minimal(), OpenDDS::XTypes::TI_PLAIN_ARRAY_LARGE, OpenDDS::XTypes::TI_PLAIN_ARRAY_SMALL, OpenDDS::XTypes::TI_PLAIN_MAP_LARGE, OpenDDS::XTypes::TI_PLAIN_MAP_SMALL, OpenDDS::XTypes::TI_PLAIN_SEQUENCE_LARGE, OpenDDS::XTypes::TI_PLAIN_SEQUENCE_SMALL, OpenDDS::XTypes::TI_STRING16_LARGE, OpenDDS::XTypes::TI_STRING16_SMALL, OpenDDS::XTypes::TI_STRING8_LARGE, OpenDDS::XTypes::TI_STRING8_SMALL, OpenDDS::XTypes::TI_STRONGLY_CONNECTED_COMPONENT, OpenDDS::XTypes::TK_BOOLEAN, OpenDDS::XTypes::TK_BYTE, OpenDDS::XTypes::TK_CHAR16, OpenDDS::XTypes::TK_CHAR8, OpenDDS::XTypes::TK_FLOAT128, OpenDDS::XTypes::TK_FLOAT32, OpenDDS::XTypes::TK_FLOAT64, OpenDDS::XTypes::TK_INT16, OpenDDS::XTypes::TK_INT32, OpenDDS::XTypes::TK_INT64, OpenDDS::XTypes::TK_INT8, OpenDDS::XTypes::TK_UINT16, OpenDDS::XTypes::TK_UINT32, OpenDDS::XTypes::TK_UINT64, and OpenDDS::XTypes::TK_UINT8.

97 {
98  if (ta == tb) {
99  return true;
100  }
101 
102  switch (ta.kind()) {
103  case TK_BOOLEAN:
104  case TK_BYTE:
105  case TK_INT16:
106  case TK_INT32:
107  case TK_INT64:
108  case TK_UINT16:
109  case TK_UINT32:
110  case TK_UINT64:
111  case TK_FLOAT32:
112  case TK_FLOAT64:
113  case TK_FLOAT128:
114  case TK_INT8:
115  case TK_UINT8:
116  case TK_CHAR8:
117  case TK_CHAR16:
118  return assignable_primitive(ta, tb);
119  case TI_STRING8_SMALL:
120  case TI_STRING8_LARGE:
121  case TI_STRING16_SMALL:
122  case TI_STRING16_LARGE:
123  return assignable_string(ta, tb);
126  return assignable_plain_sequence(ta, tb);
129  return assignable_plain_array(ta, tb);
130  case TI_PLAIN_MAP_SMALL:
131  case TI_PLAIN_MAP_LARGE:
132  return assignable_plain_map(ta, tb);
134  // No rule in the spec for strongly connected components
135  return false;
136  case EK_COMPLETE:
137  // Assuming only equivalence kind of EK_MINIMAL is supported
138  return false;
139  case EK_MINIMAL: {
140  const MinimalTypeObject& base_type_a = lookup_minimal(ta);
141  return assignable(TypeObject(base_type_a), tb);
142  }
143  default:
144  return false; // Future extensions
145  }
146 }
const TypeKind TK_INT32
Definition: TypeObject.h:217
const TypeKind TK_FLOAT128
Definition: TypeObject.h:224
const TypeIdentifierKind TI_STRING8_LARGE
Definition: TypeObject.h:256
const TypeKind TK_BYTE
Definition: TypeObject.h:215
const TypeKind TK_INT16
Definition: TypeObject.h:216
const TypeIdentifierKind TI_PLAIN_SEQUENCE_LARGE
Definition: TypeObject.h:261
const MinimalTypeObject & lookup_minimal(const TypeIdentifier &ti) const
const TypeKind TK_UINT16
Definition: TypeObject.h:219
const TypeIdentifierKind TI_STRING16_LARGE
Definition: TypeObject.h:258
const TypeKind TK_INT8
Definition: TypeObject.h:225
const TypeIdentifierKind TI_STRING8_SMALL
Definition: TypeObject.h:255
bool assignable_plain_array(const TypeIdentifier &ta, const TypeIdentifier &tb) const
The first type must be a plain array type. The second type can be anything.
const EquivalenceKind EK_COMPLETE
Definition: TypeObject.h:206
const TypeIdentifierKind TI_PLAIN_MAP_LARGE
Definition: TypeObject.h:267
const TypeKind TK_BOOLEAN
Definition: TypeObject.h:214
const TypeIdentifierKind TI_PLAIN_MAP_SMALL
Definition: TypeObject.h:266
const TypeIdentifierKind TI_PLAIN_ARRAY_LARGE
Definition: TypeObject.h:264
const TypeIdentifierKind TI_PLAIN_ARRAY_SMALL
Definition: TypeObject.h:263
const TypeKind TK_CHAR8
Definition: TypeObject.h:227
bool assignable(const TypeObject &ta, const TypeObject &tb) const
Both input type objects must be minimal.
const TypeKind TK_FLOAT32
Definition: TypeObject.h:222
bool assignable_plain_map(const TypeIdentifier &ta, const TypeIdentifier &tb) const
The first type must be a plain map type. The second type can be anything.
const TypeKind TK_UINT64
Definition: TypeObject.h:221
const TypeKind TK_INT64
Definition: TypeObject.h:218
const TypeKind TK_UINT32
Definition: TypeObject.h:220
const TypeIdentifierKind TI_PLAIN_SEQUENCE_SMALL
Definition: TypeObject.h:260
const EquivalenceKind EK_MINIMAL
Definition: TypeObject.h:205
const TypeIdentifierKind TI_STRING16_SMALL
Definition: TypeObject.h:257
const TypeIdentifierKind TI_STRONGLY_CONNECTED_COMPONENT
Definition: TypeObject.h:269
const TypeKind TK_UINT8
Definition: TypeObject.h:226
bool assignable_plain_sequence(const TypeIdentifier &ta, const TypeIdentifier &tb) const
The first type must be a plain sequence type. The second type can be anything.
bool assignable_string(const TypeIdentifier &ta, const TypeIdentifier &tb) const
The first type must be a string type. The second type can be anything.
bool assignable_primitive(const TypeIdentifier &ta, const TypeIdentifier &tb) const
The first type must be a primitive type. The second type can be anything.
const TypeKind TK_CHAR16
Definition: TypeObject.h:228
const TypeKind TK_FLOAT64
Definition: TypeObject.h:223

◆ assignable() [4/4]

bool OpenDDS::XTypes::TypeAssignability::assignable ( const TypeIdentifier ta,
const TypeObject tb 
) const

The second argument must be a minimal type object.

Definition at line 151 of file TypeAssignability.cpp.

References assignable(), assignable_plain_array(), assignable_plain_map(), assignable_plain_sequence(), assignable_primitive(), assignable_string(), OpenDDS::XTypes::EK_COMPLETE, OpenDDS::XTypes::EK_MINIMAL, get_base_type(), OpenDDS::XTypes::TypeIdentifier::kind(), OpenDDS::XTypes::MinimalTypeObject::kind, OpenDDS::XTypes::TypeObject::kind, lookup_minimal(), OpenDDS::XTypes::TypeObject::minimal, OpenDDS::XTypes::TI_PLAIN_ARRAY_LARGE, OpenDDS::XTypes::TI_PLAIN_ARRAY_SMALL, OpenDDS::XTypes::TI_PLAIN_MAP_LARGE, OpenDDS::XTypes::TI_PLAIN_MAP_SMALL, OpenDDS::XTypes::TI_PLAIN_SEQUENCE_LARGE, OpenDDS::XTypes::TI_PLAIN_SEQUENCE_SMALL, OpenDDS::XTypes::TI_STRING16_LARGE, OpenDDS::XTypes::TI_STRING16_SMALL, OpenDDS::XTypes::TI_STRING8_LARGE, OpenDDS::XTypes::TI_STRING8_SMALL, OpenDDS::XTypes::TI_STRONGLY_CONNECTED_COMPONENT, OpenDDS::XTypes::TK_ALIAS, OpenDDS::XTypes::TK_BOOLEAN, OpenDDS::XTypes::TK_BYTE, OpenDDS::XTypes::TK_CHAR16, OpenDDS::XTypes::TK_CHAR8, OpenDDS::XTypes::TK_FLOAT128, OpenDDS::XTypes::TK_FLOAT32, OpenDDS::XTypes::TK_FLOAT64, OpenDDS::XTypes::TK_INT16, OpenDDS::XTypes::TK_INT32, OpenDDS::XTypes::TK_INT64, OpenDDS::XTypes::TK_INT8, OpenDDS::XTypes::TK_UINT16, OpenDDS::XTypes::TK_UINT32, OpenDDS::XTypes::TK_UINT64, and OpenDDS::XTypes::TK_UINT8.

153 {
154  if (EK_MINIMAL == tb.kind) {
155  if (TK_ALIAS == tb.minimal.kind) {
156  return assignable(ta, get_base_type(tb.minimal));
157  }
158 
159  switch (ta.kind()) {
160  case TK_BOOLEAN:
161  case TK_BYTE:
162  case TK_INT16:
163  case TK_INT32:
164  case TK_INT64:
165  case TK_UINT16:
166  case TK_UINT32:
167  case TK_UINT64:
168  case TK_FLOAT32:
169  case TK_FLOAT64:
170  case TK_FLOAT128:
171  case TK_INT8:
172  case TK_UINT8:
173  case TK_CHAR8:
174  case TK_CHAR16:
175  return assignable_primitive(ta, tb.minimal);
176  case TI_STRING8_SMALL:
177  case TI_STRING8_LARGE:
178  case TI_STRING16_SMALL:
179  case TI_STRING16_LARGE:
180  return assignable_string(ta, tb.minimal);
183  return assignable_plain_sequence(ta, tb.minimal);
186  return assignable_plain_array(ta, tb.minimal);
187  case TI_PLAIN_MAP_SMALL:
188  case TI_PLAIN_MAP_LARGE:
189  return assignable_plain_map(ta, tb.minimal);
191  return false;
192  case EK_COMPLETE:
193  return false;
194  case EK_MINIMAL: {
195  const MinimalTypeObject& tobj_a = lookup_minimal(ta);
196  return assignable(TypeObject(tobj_a), tb);
197  }
198  default:
199  return false;
200  }
201  }
202 
203  return false;
204 }
const TypeKind TK_INT32
Definition: TypeObject.h:217
const TypeKind TK_FLOAT128
Definition: TypeObject.h:224
const TypeIdentifierKind TI_STRING8_LARGE
Definition: TypeObject.h:256
const TypeKind TK_BYTE
Definition: TypeObject.h:215
const TypeKind TK_INT16
Definition: TypeObject.h:216
const TypeIdentifierKind TI_PLAIN_SEQUENCE_LARGE
Definition: TypeObject.h:261
const MinimalTypeObject & lookup_minimal(const TypeIdentifier &ti) const
const TypeKind TK_UINT16
Definition: TypeObject.h:219
const TypeIdentifierKind TI_STRING16_LARGE
Definition: TypeObject.h:258
const TypeIdentifier & get_base_type(const MinimalTypeObject &type) const
The input must be of type TK_ALIAS Return the non-alias base type identifier of the input...
const TypeKind TK_INT8
Definition: TypeObject.h:225
const TypeIdentifierKind TI_STRING8_SMALL
Definition: TypeObject.h:255
bool assignable_plain_array(const TypeIdentifier &ta, const TypeIdentifier &tb) const
The first type must be a plain array type. The second type can be anything.
const EquivalenceKind EK_COMPLETE
Definition: TypeObject.h:206
const TypeIdentifierKind TI_PLAIN_MAP_LARGE
Definition: TypeObject.h:267
const TypeKind TK_BOOLEAN
Definition: TypeObject.h:214
const TypeIdentifierKind TI_PLAIN_MAP_SMALL
Definition: TypeObject.h:266
const TypeIdentifierKind TI_PLAIN_ARRAY_LARGE
Definition: TypeObject.h:264
const TypeIdentifierKind TI_PLAIN_ARRAY_SMALL
Definition: TypeObject.h:263
const TypeKind TK_CHAR8
Definition: TypeObject.h:227
bool assignable(const TypeObject &ta, const TypeObject &tb) const
Both input type objects must be minimal.
const TypeKind TK_FLOAT32
Definition: TypeObject.h:222
bool assignable_plain_map(const TypeIdentifier &ta, const TypeIdentifier &tb) const
The first type must be a plain map type. The second type can be anything.
const TypeKind TK_UINT64
Definition: TypeObject.h:221
const TypeKind TK_INT64
Definition: TypeObject.h:218
const TypeKind TK_UINT32
Definition: TypeObject.h:220
const TypeKind TK_ALIAS
Definition: TypeObject.h:235
const TypeIdentifierKind TI_PLAIN_SEQUENCE_SMALL
Definition: TypeObject.h:260
const EquivalenceKind EK_MINIMAL
Definition: TypeObject.h:205
const TypeIdentifierKind TI_STRING16_SMALL
Definition: TypeObject.h:257
const TypeIdentifierKind TI_STRONGLY_CONNECTED_COMPONENT
Definition: TypeObject.h:269
const TypeKind TK_UINT8
Definition: TypeObject.h:226
bool assignable_plain_sequence(const TypeIdentifier &ta, const TypeIdentifier &tb) const
The first type must be a plain sequence type. The second type can be anything.
bool assignable_string(const TypeIdentifier &ta, const TypeIdentifier &tb) const
The first type must be a string type. The second type can be anything.
bool assignable_primitive(const TypeIdentifier &ta, const TypeIdentifier &tb) const
The first type must be a primitive type. The second type can be anything.
const TypeKind TK_CHAR16
Definition: TypeObject.h:228
const TypeKind TK_FLOAT64
Definition: TypeObject.h:223

◆ assignable_alias()

bool OpenDDS::XTypes::TypeAssignability::assignable_alias ( const MinimalTypeObject ta,
const MinimalTypeObject tb 
) const
private

At least one input type object must be TK_ALIAS.

Definition at line 209 of file TypeAssignability.cpp.

References OpenDDS::XTypes::MinimalTypeObject::alias_type, assignable(), assignable_annotation(), assignable_array(), assignable_bitmask(), assignable_bitset(), assignable_enum(), assignable_map(), assignable_plain_array(), assignable_plain_map(), assignable_plain_sequence(), assignable_primitive(), assignable_sequence(), assignable_string(), assignable_struct(), assignable_union(), OpenDDS::XTypes::MinimalAliasType::body, OpenDDS::XTypes::MinimalAliasBody::common, OpenDDS::XTypes::EK_COMPLETE, OpenDDS::XTypes::EK_MINIMAL, OpenDDS::XTypes::TypeIdentifier::kind(), OpenDDS::XTypes::MinimalTypeObject::kind, lookup_minimal(), OpenDDS::XTypes::CommonAliasBody::related_type, OpenDDS::XTypes::TI_PLAIN_ARRAY_LARGE, OpenDDS::XTypes::TI_PLAIN_ARRAY_SMALL, OpenDDS::XTypes::TI_PLAIN_MAP_LARGE, OpenDDS::XTypes::TI_PLAIN_MAP_SMALL, OpenDDS::XTypes::TI_PLAIN_SEQUENCE_LARGE, OpenDDS::XTypes::TI_PLAIN_SEQUENCE_SMALL, OpenDDS::XTypes::TI_STRING16_LARGE, OpenDDS::XTypes::TI_STRING16_SMALL, OpenDDS::XTypes::TI_STRING8_LARGE, OpenDDS::XTypes::TI_STRING8_SMALL, OpenDDS::XTypes::TI_STRONGLY_CONNECTED_COMPONENT, OpenDDS::XTypes::TK_ALIAS, OpenDDS::XTypes::TK_ANNOTATION, OpenDDS::XTypes::TK_ARRAY, OpenDDS::XTypes::TK_BITMASK, OpenDDS::XTypes::TK_BITSET, OpenDDS::XTypes::TK_BOOLEAN, OpenDDS::XTypes::TK_BYTE, OpenDDS::XTypes::TK_CHAR16, OpenDDS::XTypes::TK_CHAR8, OpenDDS::XTypes::TK_ENUM, OpenDDS::XTypes::TK_FLOAT128, OpenDDS::XTypes::TK_FLOAT32, OpenDDS::XTypes::TK_FLOAT64, OpenDDS::XTypes::TK_INT16, OpenDDS::XTypes::TK_INT32, OpenDDS::XTypes::TK_INT64, OpenDDS::XTypes::TK_INT8, OpenDDS::XTypes::TK_MAP, OpenDDS::XTypes::TK_SEQUENCE, OpenDDS::XTypes::TK_STRUCTURE, OpenDDS::XTypes::TK_UINT16, OpenDDS::XTypes::TK_UINT32, OpenDDS::XTypes::TK_UINT64, OpenDDS::XTypes::TK_UINT8, and OpenDDS::XTypes::TK_UNION.

Referenced by assignable().

211 {
212  if (TK_ALIAS == ta.kind && TK_ALIAS != tb.kind) {
213  const TypeIdentifier& tia = ta.alias_type.body.common.related_type;
214  switch (tia.kind()) {
215  case TK_BOOLEAN:
216  case TK_BYTE:
217  case TK_INT16:
218  case TK_INT32:
219  case TK_INT64:
220  case TK_UINT16:
221  case TK_UINT32:
222  case TK_UINT64:
223  case TK_FLOAT32:
224  case TK_FLOAT64:
225  case TK_FLOAT128:
226  case TK_INT8:
227  case TK_UINT8:
228  case TK_CHAR8:
229  case TK_CHAR16:
230  return assignable_primitive(tia, tb);
231  case TI_STRING8_SMALL:
232  case TI_STRING8_LARGE:
233  case TI_STRING16_SMALL:
234  case TI_STRING16_LARGE:
235  return assignable_string(tia, tb);
238  return assignable_plain_sequence(tia, tb);
241  return assignable_plain_array(tia, tb);
242  case TI_PLAIN_MAP_SMALL:
243  case TI_PLAIN_MAP_LARGE:
244  return assignable_plain_map(tia, tb);
246  // Does alias ever have SCC as its base type?
247  return false;
248  case EK_COMPLETE:
249  // Supporting minimal base type only
250  return false;
251  case EK_MINIMAL: {
252  const MinimalTypeObject& base_type_a = lookup_minimal(tia);
253  return assignable(TypeObject(base_type_a), TypeObject(tb));
254  }
255  default:
256  return false; // Future extensions
257  }
258  } else if (TK_ALIAS != ta.kind && TK_ALIAS == tb.kind) {
259  const TypeIdentifier& tib = tb.alias_type.body.common.related_type;
260  switch (ta.kind) {
261  case TK_ANNOTATION:
262  return assignable_annotation(ta, tib);
263  case TK_STRUCTURE:
264  return assignable_struct(ta, tib);
265  case TK_UNION:
266  return assignable_union(ta, tib);
267  case TK_BITSET:
268  return assignable_bitset(ta, tib);
269  case TK_SEQUENCE:
270  return assignable_sequence(ta, tib);
271  case TK_ARRAY:
272  return assignable_array(ta, tib);
273  case TK_MAP:
274  return assignable_map(ta, tib);
275  case TK_ENUM:
276  return assignable_enum(ta, tib);
277  case TK_BITMASK:
278  return assignable_bitmask(ta, tib);
279  default:
280  return false; // Future extensions
281  }
282  } else if (TK_ALIAS == ta.kind && TK_ALIAS == tb.kind) {
283  const TypeIdentifier& tia = ta.alias_type.body.common.related_type;
284  const TypeIdentifier& tib = tb.alias_type.body.common.related_type;
285  return assignable(tia, tib);
286  }
287 
288  return false;
289 }
const TypeKind TK_SEQUENCE
Definition: TypeObject.h:248
const TypeKind TK_INT32
Definition: TypeObject.h:217
const TypeKind TK_FLOAT128
Definition: TypeObject.h:224
const TypeIdentifierKind TI_STRING8_LARGE
Definition: TypeObject.h:256
const TypeKind TK_BYTE
Definition: TypeObject.h:215
const TypeKind TK_UNION
Definition: TypeObject.h:244
const TypeKind TK_INT16
Definition: TypeObject.h:216
const TypeIdentifierKind TI_PLAIN_SEQUENCE_LARGE
Definition: TypeObject.h:261
const MinimalTypeObject & lookup_minimal(const TypeIdentifier &ti) const
const TypeKind TK_UINT16
Definition: TypeObject.h:219
bool assignable_enum(const MinimalTypeObject &ta, const MinimalTypeObject &tb) const
The first type must be TK_ENUM. The second type must not be TK_ALIAS.
bool assignable_struct(const MinimalTypeObject &ta, const MinimalTypeObject &tb) const
The first type must be TK_STRUCTURE. The second type must not be TK_ALIAS.
const TypeIdentifierKind TI_STRING16_LARGE
Definition: TypeObject.h:258
const TypeKind TK_INT8
Definition: TypeObject.h:225
const TypeIdentifierKind TI_STRING8_SMALL
Definition: TypeObject.h:255
bool assignable_array(const MinimalTypeObject &ta, const MinimalTypeObject &tb) const
The first type must be TK_ARRAY. The second type must not be TK_ALIAS.
bool assignable_plain_array(const TypeIdentifier &ta, const TypeIdentifier &tb) const
The first type must be a plain array type. The second type can be anything.
const EquivalenceKind EK_COMPLETE
Definition: TypeObject.h:206
const TypeIdentifierKind TI_PLAIN_MAP_LARGE
Definition: TypeObject.h:267
bool assignable_annotation(const MinimalTypeObject &ta, const MinimalTypeObject &tb) const
The first type must be TK_ANNOTATION. The second type must not be TK_ALIAS.
const TypeKind TK_BOOLEAN
Definition: TypeObject.h:214
const TypeIdentifierKind TI_PLAIN_MAP_SMALL
Definition: TypeObject.h:266
const TypeIdentifierKind TI_PLAIN_ARRAY_LARGE
Definition: TypeObject.h:264
const TypeIdentifierKind TI_PLAIN_ARRAY_SMALL
Definition: TypeObject.h:263
const TypeKind TK_BITMASK
Definition: TypeObject.h:239
bool assignable_sequence(const MinimalTypeObject &ta, const MinimalTypeObject &tb) const
The first type must be TK_SEQUENCE. The second type must not be TK_ALIAS.
const TypeKind TK_CHAR8
Definition: TypeObject.h:227
bool assignable_union(const MinimalTypeObject &ta, const MinimalTypeObject &tb) const
The first type must be TK_UNION. The second type must not be TK_ALIAS.
const TypeKind TK_STRUCTURE
Definition: TypeObject.h:243
bool assignable(const TypeObject &ta, const TypeObject &tb) const
Both input type objects must be minimal.
const TypeKind TK_FLOAT32
Definition: TypeObject.h:222
bool assignable_plain_map(const TypeIdentifier &ta, const TypeIdentifier &tb) const
The first type must be a plain map type. The second type can be anything.
const TypeKind TK_UINT64
Definition: TypeObject.h:221
const TypeKind TK_INT64
Definition: TypeObject.h:218
const TypeKind TK_UINT32
Definition: TypeObject.h:220
const TypeKind TK_ALIAS
Definition: TypeObject.h:235
const TypeIdentifierKind TI_PLAIN_SEQUENCE_SMALL
Definition: TypeObject.h:260
const TypeKind TK_ANNOTATION
Definition: TypeObject.h:242
const TypeKind TK_ENUM
Definition: TypeObject.h:238
const EquivalenceKind EK_MINIMAL
Definition: TypeObject.h:205
const TypeIdentifierKind TI_STRING16_SMALL
Definition: TypeObject.h:257
bool assignable_bitmask(const MinimalTypeObject &ta, const MinimalTypeObject &tb) const
The first type must be TK_BITMASK. The second type must not be TK_ALIAS.
const TypeIdentifierKind TI_STRONGLY_CONNECTED_COMPONENT
Definition: TypeObject.h:269
const TypeKind TK_ARRAY
Definition: TypeObject.h:249
bool assignable_map(const MinimalTypeObject &ta, const MinimalTypeObject &tb) const
The first type must be TK_MAP. The second type must not be TK_ALIAS.
const TypeKind TK_UINT8
Definition: TypeObject.h:226
bool assignable_plain_sequence(const TypeIdentifier &ta, const TypeIdentifier &tb) const
The first type must be a plain sequence type. The second type can be anything.
bool assignable_string(const TypeIdentifier &ta, const TypeIdentifier &tb) const
The first type must be a string type. The second type can be anything.
bool assignable_primitive(const TypeIdentifier &ta, const TypeIdentifier &tb) const
The first type must be a primitive type. The second type can be anything.
const TypeKind TK_MAP
Definition: TypeObject.h:250
bool assignable_bitset(const MinimalTypeObject &ta, const MinimalTypeObject &tb) const
The first type must be TK_BITSET. The second type must not be TK_ALIAS.
const TypeKind TK_CHAR16
Definition: TypeObject.h:228
const TypeKind TK_FLOAT64
Definition: TypeObject.h:223
const TypeKind TK_BITSET
Definition: TypeObject.h:245

◆ assignable_annotation() [1/2]

bool OpenDDS::XTypes::TypeAssignability::assignable_annotation ( const MinimalTypeObject ta,
const MinimalTypeObject tb 
) const
private

The first type must be TK_ANNOTATION. The second type must not be TK_ALIAS.

Definition at line 295 of file TypeAssignability.cpp.

Referenced by assignable(), and assignable_alias().

297 {
298  // No rule for annotation in the spec
299  return false;
300 }

◆ assignable_annotation() [2/2]

bool OpenDDS::XTypes::TypeAssignability::assignable_annotation ( const MinimalTypeObject ta,
const TypeIdentifier tb 
) const
private

The first type must be TK_ANNOTATION. The second type can be anything.

Definition at line 306 of file TypeAssignability.cpp.

308 {
309  // No rule for annotation in the spec
310  return false;
311 }

◆ assignable_array() [1/2]

bool OpenDDS::XTypes::TypeAssignability::assignable_array ( const MinimalTypeObject ta,
const MinimalTypeObject tb 
) const
private

The first type must be TK_ARRAY. The second type must not be TK_ALIAS.

Definition at line 938 of file TypeAssignability.cpp.

References OpenDDS::XTypes::MinimalTypeObject::array_type, OpenDDS::XTypes::CommonArrayHeader::bound_seq, OpenDDS::XTypes::MinimalCollectionElement::common, OpenDDS::XTypes::MinimalArrayHeader::common, OpenDDS::XTypes::MinimalArrayType::element, OpenDDS::XTypes::MinimalArrayType::header, OpenDDS::XTypes::MinimalTypeObject::kind, OpenDDS::XTypes::Sequence< T >::members, strongly_assignable(), OpenDDS::XTypes::TK_ARRAY, and OpenDDS::XTypes::CommonCollectionElement::type.

Referenced by assignable(), assignable_alias(), and assignable_array().

940 {
941  if (TK_ARRAY != tb.kind) {
942  return false;
943  }
944 
945  // Bounds must match
946  const LBoundSeq& bounds_a = ta.array_type.header.common.bound_seq;
947  const LBoundSeq& bounds_b = tb.array_type.header.common.bound_seq;
948  if (bounds_a.members.size() != bounds_b.members.size()) {
949  return false;
950  }
951 
952  for (unsigned i = 0; i < bounds_a.members.size(); ++i) {
953  if (bounds_a.members[i] != bounds_b.members[i]) {
954  return false;
955  }
956  }
957  return strongly_assignable(ta.array_type.element.common.type,
958  tb.array_type.element.common.type);
959 }
bool strongly_assignable(const TypeIdentifier &ta, const TypeIdentifier &tb) const
If types T1 and T2 are equivalent using the MINIMAL relation, or alternatively if T1 is-assignable-fr...
Sequence< LBound > LBoundSeq
Definition: TypeObject.h:313
const TypeKind TK_ARRAY
Definition: TypeObject.h:249

◆ assignable_array() [2/2]

bool OpenDDS::XTypes::TypeAssignability::assignable_array ( const MinimalTypeObject ta,
const TypeIdentifier tb 
) const
private

The first type must be TK_ARRAY. The second type can be anything.

Definition at line 965 of file TypeAssignability.cpp.

References OpenDDS::XTypes::MinimalTypeObject::alias_type, OpenDDS::XTypes::MinimalTypeObject::array_type, assignable_array(), OpenDDS::XTypes::MinimalAliasType::body, OpenDDS::XTypes::CommonArrayHeader::bound_seq, OpenDDS::XTypes::MinimalAliasBody::common, OpenDDS::XTypes::MinimalCollectionElement::common, OpenDDS::XTypes::MinimalArrayHeader::common, OpenDDS::XTypes::EK_COMPLETE, OpenDDS::XTypes::EK_MINIMAL, OpenDDS::XTypes::MinimalArrayType::element, OpenDDS::XTypes::MinimalArrayType::header, OpenDDS::XTypes::TypeIdentifier::kind(), OpenDDS::XTypes::MinimalTypeObject::kind, lookup_minimal(), OpenDDS::XTypes::Sequence< T >::members, OpenDDS::XTypes::CommonAliasBody::related_type, strongly_assignable(), OpenDDS::XTypes::TI_PLAIN_ARRAY_LARGE, OpenDDS::XTypes::TI_PLAIN_ARRAY_SMALL, OpenDDS::XTypes::TK_ALIAS, OpenDDS::XTypes::TK_ARRAY, and OpenDDS::XTypes::CommonCollectionElement::type.

967 {
968  const LBoundSeq& bounds_a = ta.array_type.header.common.bound_seq;
969  if (TI_PLAIN_ARRAY_SMALL == tb.kind()) {
970  const SBoundSeq& bounds_b = tb.array_sdefn().array_bound_seq;
971  if (bounds_a.members.size() != bounds_b.members.size()) {
972  return false;
973  }
974 
975  for (unsigned i = 0; i < bounds_a.members.size(); ++i) {
976  if (bounds_a.members[i] != static_cast<LBound>(bounds_b.members[i])) {
977  return false;
978  }
979  }
980 
981  return strongly_assignable(ta.array_type.element.common.type,
982  *tb.array_sdefn().element_identifier);
983  } else if (TI_PLAIN_ARRAY_LARGE == tb.kind()) {
984  const LBoundSeq& bounds_b = tb.array_ldefn().array_bound_seq;
985  if (bounds_a.members.size() != bounds_b.members.size()) {
986  return false;
987  }
988 
989  for (unsigned i = 0; i < bounds_a.members.size(); ++i) {
990  if (bounds_a.members[i] != bounds_b.members[i]) {
991  return false;
992  }
993  }
994  return strongly_assignable(ta.array_type.element.common.type,
995  *tb.array_ldefn().element_identifier);
996  } else if (EK_MINIMAL == tb.kind()) {
997  const MinimalTypeObject& tob = lookup_minimal(tb);
998  if (TK_ARRAY == tob.kind) {
999  return assignable_array(ta, tob);
1000  } else if (TK_ALIAS == tob.kind) {
1001  const TypeIdentifier& base = tob.alias_type.body.common.related_type;
1002  return assignable_array(ta, base);
1003  }
1004  } else if (EK_COMPLETE == tb.kind()) {
1005  // Assuming tb.kind of EK_COMPLETE is not supported
1006  return false;
1007  }
1008 
1009  return false;
1010 }
const MinimalTypeObject & lookup_minimal(const TypeIdentifier &ti) const
bool assignable_array(const MinimalTypeObject &ta, const MinimalTypeObject &tb) const
The first type must be TK_ARRAY. The second type must not be TK_ALIAS.
bool strongly_assignable(const TypeIdentifier &ta, const TypeIdentifier &tb) const
If types T1 and T2 are equivalent using the MINIMAL relation, or alternatively if T1 is-assignable-fr...
const EquivalenceKind EK_COMPLETE
Definition: TypeObject.h:206
const TypeIdentifierKind TI_PLAIN_ARRAY_LARGE
Definition: TypeObject.h:264
const TypeIdentifierKind TI_PLAIN_ARRAY_SMALL
Definition: TypeObject.h:263
Sequence< SBound > SBoundSeq
Definition: TypeObject.h:318
const TypeKind TK_ALIAS
Definition: TypeObject.h:235
Sequence< LBound > LBoundSeq
Definition: TypeObject.h:313
const EquivalenceKind EK_MINIMAL
Definition: TypeObject.h:205
const TypeKind TK_ARRAY
Definition: TypeObject.h:249

◆ assignable_bitmask() [1/2]

bool OpenDDS::XTypes::TypeAssignability::assignable_bitmask ( const MinimalTypeObject ta,
const MinimalTypeObject tb 
) const
private

The first type must be TK_BITMASK. The second type must not be TK_ALIAS.

Definition at line 1175 of file TypeAssignability.cpp.

References OpenDDS::XTypes::CommonEnumeratedHeader::bit_bound, OpenDDS::XTypes::MinimalTypeObject::bitmask_type, OpenDDS::XTypes::MinimalEnumeratedHeader::common, OpenDDS::XTypes::MinimalBitmaskType::header, OpenDDS::XTypes::MinimalTypeObject::kind, and OpenDDS::XTypes::TK_BITMASK.

Referenced by assignable(), assignable_alias(), and assignable_bitmask().

1177 {
1178  if (TK_BITMASK == tb.kind) {
1179  return ta.bitmask_type.header.common.bit_bound ==
1180  tb.bitmask_type.header.common.bit_bound;
1181  }
1182 
1183  return false;
1184 }
const TypeKind TK_BITMASK
Definition: TypeObject.h:239

◆ assignable_bitmask() [2/2]

bool OpenDDS::XTypes::TypeAssignability::assignable_bitmask ( const MinimalTypeObject ta,
const TypeIdentifier tb 
) const
private

The first type must be TK_BITMASK. The second type can be anything.

Definition at line 1190 of file TypeAssignability.cpp.

References OpenDDS::XTypes::MinimalTypeObject::alias_type, assignable_bitmask(), OpenDDS::XTypes::CommonEnumeratedHeader::bit_bound, OpenDDS::XTypes::MinimalTypeObject::bitmask_type, OpenDDS::XTypes::MinimalAliasType::body, OpenDDS::XTypes::MinimalAliasBody::common, OpenDDS::XTypes::MinimalEnumeratedHeader::common, OpenDDS::XTypes::EK_COMPLETE, OpenDDS::XTypes::EK_MINIMAL, OpenDDS::XTypes::MinimalBitmaskType::header, OpenDDS::XTypes::TypeIdentifier::kind(), OpenDDS::XTypes::MinimalTypeObject::kind, lookup_minimal(), OpenDDS::XTypes::CommonAliasBody::related_type, OpenDDS::XTypes::TK_ALIAS, OpenDDS::XTypes::TK_BITMASK, OpenDDS::XTypes::TK_UINT16, OpenDDS::XTypes::TK_UINT32, OpenDDS::XTypes::TK_UINT64, and OpenDDS::XTypes::TK_UINT8.

1192 {
1193  BitBound ta_bit_bound = ta.bitmask_type.header.common.bit_bound;
1194  if (TK_UINT8 == tb.kind()) {
1195  return 1 <= ta_bit_bound && ta_bit_bound <= 8;
1196  } else if (TK_UINT16 == tb.kind()) {
1197  return 9 <= ta_bit_bound && ta_bit_bound <= 16;
1198  } else if (TK_UINT32 == tb.kind()) {
1199  return 17 <= ta_bit_bound && ta_bit_bound <= 32;
1200  } else if (TK_UINT64 == tb.kind()) {
1201  return 33 <= ta_bit_bound && ta_bit_bound <= 64;
1202  } else if (EK_MINIMAL == tb.kind()) {
1203  const MinimalTypeObject& tob = lookup_minimal(tb);
1204  if (TK_BITMASK == tob.kind) {
1205  return assignable_bitmask(ta, tob);
1206  } else if (TK_ALIAS == tob.kind) {
1207  const TypeIdentifier& base = tob.alias_type.body.common.related_type;
1208  return assignable_bitmask(ta, base);
1209  }
1210  } else if (EK_COMPLETE == tb.kind()) {
1211  // Assuming tb.kind of EK_COMPLETE is not supported
1212  return false;
1213  }
1214 
1215  return false;
1216 }
const MinimalTypeObject & lookup_minimal(const TypeIdentifier &ti) const
const TypeKind TK_UINT16
Definition: TypeObject.h:219
ACE_CDR::UShort BitBound
Definition: TypeObject.h:2478
const EquivalenceKind EK_COMPLETE
Definition: TypeObject.h:206
const TypeKind TK_BITMASK
Definition: TypeObject.h:239
const TypeKind TK_UINT64
Definition: TypeObject.h:221
const TypeKind TK_UINT32
Definition: TypeObject.h:220
const TypeKind TK_ALIAS
Definition: TypeObject.h:235
const EquivalenceKind EK_MINIMAL
Definition: TypeObject.h:205
bool assignable_bitmask(const MinimalTypeObject &ta, const MinimalTypeObject &tb) const
The first type must be TK_BITMASK. The second type must not be TK_ALIAS.
const TypeKind TK_UINT8
Definition: TypeObject.h:226

◆ assignable_bitset() [1/2]

bool OpenDDS::XTypes::TypeAssignability::assignable_bitset ( const MinimalTypeObject ta,
const MinimalTypeObject tb 
) const
private

The first type must be TK_BITSET. The second type must not be TK_ALIAS.

Definition at line 873 of file TypeAssignability.cpp.

Referenced by assignable(), and assignable_alias().

875 {
876  // No rule for bitset in the spec
877  return false;
878 }

◆ assignable_bitset() [2/2]

bool OpenDDS::XTypes::TypeAssignability::assignable_bitset ( const MinimalTypeObject ta,
const TypeIdentifier tb 
) const
private

The first type must be TK_BITSET. The second type can be anything.

Definition at line 884 of file TypeAssignability.cpp.

886 {
887  // No rule for bitset in the spec
888  return false;
889 }

◆ assignable_enum() [1/2]

bool OpenDDS::XTypes::TypeAssignability::assignable_enum ( const MinimalTypeObject ta,
const MinimalTypeObject tb 
) const
private

The first type must be TK_ENUM. The second type must not be TK_ALIAS.

Definition at line 1065 of file TypeAssignability.cpp.

References OpenDDS::XTypes::CommonEnumeratedHeader::bit_bound, OpenDDS::XTypes::MinimalEnumeratedHeader::common, OpenDDS::XTypes::MinimalEnumeratedType::enum_flags, OpenDDS::XTypes::MinimalTypeObject::enumerated_type, OpenDDS::XTypes::MinimalEnumeratedType::header, OpenDDS::XTypes::IS_APPENDABLE, OpenDDS::XTypes::IS_FINAL, OpenDDS::XTypes::IS_MUTABLE, OpenDDS::XTypes::MinimalTypeObject::kind, OpenDDS::XTypes::MinimalEnumeratedType::literal_seq, OpenDDS::XTypes::Sequence< T >::members, OpenDDS::XTypes::OPENDDS_MAP(), and OpenDDS::XTypes::TK_ENUM.

Referenced by assignable(), assignable_alias(), and assignable_enum().

1067 {
1068  if (TK_ENUM != tb.kind) {
1069  return false;
1070  }
1071 
1072  // Assuming that EnumTypeFlag is used and contains extensibility
1073  // of the containing type.
1074  const TypeFlag extensibility_mask = IS_FINAL | IS_APPENDABLE | IS_MUTABLE;
1075  TypeFlag ta_ext = ta.enumerated_type.enum_flags & extensibility_mask;
1076  TypeFlag tb_ext = tb.enumerated_type.enum_flags & extensibility_mask;
1077  if (ta_ext != tb_ext &&
1078  // Backwards compatibility.
1079  ta_ext != 0 && tb_ext != 0) {
1080  return false;
1081  }
1082 
1083  // T1.bit_bound and T2.bit_bound must be equal (DDSXTY14-34)
1084  if (ta.enumerated_type.header.common.bit_bound !=
1085  tb.enumerated_type.header.common.bit_bound) {
1086  return false;
1087  }
1088 
1089  const size_t size_a = ta.enumerated_type.literal_seq.members.size();
1090  const size_t size_b = tb.enumerated_type.literal_seq.members.size();
1091  OPENDDS_MAP(ACE_CDR::ULong, ACE_CDR::Long) ta_name_to_value;
1092  for (size_t i = 0; i < size_a; ++i) {
1093  const NameHash& h = ta.enumerated_type.literal_seq.members[i].detail.name_hash;
1094  ACE_CDR::ULong key_a = (h[0] << 24) | (h[1] << 16) | (h[2] << 8) | (h[3]);
1095  ta_name_to_value[key_a] = ta.enumerated_type.literal_seq.members[i].common.value;
1096  }
1097 
1098  // If extensibility is FINAL, both must have the same literals.
1099  if (IS_FINAL == ta_ext) {
1100  if (size_a != size_b) {
1101  return false;
1102  }
1103 
1104  for (size_t i = 0; i < size_b; ++i) {
1105  const NameHash& h = tb.enumerated_type.literal_seq.members[i].detail.name_hash;
1106  ACE_CDR::ULong key_b = (h[0] << 24) | (h[1] << 16) | (h[2] << 8) | (h[3]);
1107 
1108  // Literals that have the same name must have the same value.
1109  if (ta_name_to_value.find(key_b) == ta_name_to_value.end() ||
1110  ta_name_to_value[key_b] != tb.enumerated_type.literal_seq.members[i].common.value) {
1111  return false;
1112  }
1113  }
1114  } else {
1115  // Any literals that have the same name also have the same value
1116  for (size_t i = 0; i < size_b; ++i) {
1117  const NameHash& h = tb.enumerated_type.literal_seq.members[i].detail.name_hash;
1118  ACE_CDR::ULong key_b = (h[0] << 24) | (h[1] << 16) | (h[2] << 8) | (h[3]);
1119  if (ta_name_to_value.find(key_b) != ta_name_to_value.end() &&
1120  ta_name_to_value[key_b] != tb.enumerated_type.literal_seq.members[i].common.value) {
1121  return false;
1122  }
1123  }
1124 
1125  OPENDDS_MAP(ACE_CDR::ULong, ACE_CDR::ULong) ta_value_to_name;
1126  for (size_t i = 0; i < size_a; ++i) {
1127  ACE_CDR::ULong value_a = ta.enumerated_type.literal_seq.members[i].common.value;
1128  const NameHash& h = ta.enumerated_type.literal_seq.members[i].detail.name_hash;
1129  ACE_CDR::ULong name_a = (h[0] << 24) | (h[1] << 16) | (h[2] << 8) | (h[3]);
1130  ta_value_to_name[value_a] = name_a;
1131  }
1132 
1133  // Any literals that have the same value also have the same name
1134  for (size_t i = 0; i < size_b; ++i) {
1135  ACE_CDR::ULong value_b = tb.enumerated_type.literal_seq.members[i].common.value;
1136  const NameHash& h = tb.enumerated_type.literal_seq.members[i].detail.name_hash;
1137  ACE_CDR::ULong name_b = (h[0] << 24) | (h[1] << 16) | (h[2] << 8) | (h[3]);
1138  if (ta_value_to_name.find(value_b) != ta_value_to_name.end() &&
1139  ta_value_to_name[value_b] != name_b) {
1140  return false;
1141  }
1142  }
1143  }
1144 
1145  return true;
1146 }
const TypeFlag IS_MUTABLE
Definition: TypeObject.h:402
const TypeFlag IS_FINAL
Definition: TypeObject.h:400
ACE_UINT32 ULong
ACE_INT32 Long
ACE_CDR::UShort TypeFlag
Definition: TypeObject.h:399
const TypeKind TK_ENUM
Definition: TypeObject.h:238
const TypeFlag IS_APPENDABLE
Definition: TypeObject.h:401
typedef OPENDDS_MAP(TypeIdentifier, TypeObject) TypeMap
ACE_CDR::Octet NameHash[4]
Definition: TypeObject.h:296

◆ assignable_enum() [2/2]

bool OpenDDS::XTypes::TypeAssignability::assignable_enum ( const MinimalTypeObject ta,
const TypeIdentifier tb 
) const
private

The first type must be TK_ENUM. The second type can be anything.

Definition at line 1152 of file TypeAssignability.cpp.

References OpenDDS::XTypes::MinimalTypeObject::alias_type, assignable_enum(), OpenDDS::XTypes::MinimalAliasType::body, OpenDDS::XTypes::MinimalAliasBody::common, OpenDDS::XTypes::EK_COMPLETE, OpenDDS::XTypes::EK_MINIMAL, OpenDDS::XTypes::TypeIdentifier::kind(), OpenDDS::XTypes::MinimalTypeObject::kind, lookup_minimal(), OpenDDS::XTypes::CommonAliasBody::related_type, OpenDDS::XTypes::TK_ALIAS, and OpenDDS::XTypes::TK_ENUM.

1154 {
1155  if (EK_MINIMAL == tb.kind()) {
1156  const MinimalTypeObject& tob = lookup_minimal(tb);
1157  if (TK_ENUM == tob.kind) {
1158  return assignable_enum(ta, tob);
1159  } else if (TK_ALIAS == tob.kind) {
1160  const TypeIdentifier& base = tob.alias_type.body.common.related_type;
1161  return assignable_enum(ta, base);
1162  }
1163  } else if (EK_COMPLETE == tb.kind()) {
1164  // Assuming tb.kind of EK_COMPLETE is not supported
1165  return false;
1166  }
1167 
1168  return false;
1169 }
const MinimalTypeObject & lookup_minimal(const TypeIdentifier &ti) const
bool assignable_enum(const MinimalTypeObject &ta, const MinimalTypeObject &tb) const
The first type must be TK_ENUM. The second type must not be TK_ALIAS.
const EquivalenceKind EK_COMPLETE
Definition: TypeObject.h:206
const TypeKind TK_ALIAS
Definition: TypeObject.h:235
const TypeKind TK_ENUM
Definition: TypeObject.h:238
const EquivalenceKind EK_MINIMAL
Definition: TypeObject.h:205

◆ assignable_extended()

bool OpenDDS::XTypes::TypeAssignability::assignable_extended ( const MinimalTypeObject ta,
const MinimalTypeObject tb 
) const
private

The first type must be a future extension type kind. The second type must not be TK_ALIAS.

Definition at line 1222 of file TypeAssignability.cpp.

Referenced by assignable().

1224 {
1225  // Future extensions
1226  return false;
1227 }

◆ assignable_map() [1/2]

bool OpenDDS::XTypes::TypeAssignability::assignable_map ( const MinimalTypeObject ta,
const MinimalTypeObject tb 
) const
private

The first type must be TK_MAP. The second type must not be TK_ALIAS.

Definition at line 1016 of file TypeAssignability.cpp.

References OpenDDS::XTypes::MinimalCollectionElement::common, OpenDDS::XTypes::MinimalMapType::element, OpenDDS::XTypes::MinimalMapType::key, OpenDDS::XTypes::MinimalTypeObject::kind, OpenDDS::XTypes::MinimalTypeObject::map_type, strongly_assignable(), OpenDDS::XTypes::TK_MAP, and OpenDDS::XTypes::CommonCollectionElement::type.

Referenced by assignable(), assignable_alias(), and assignable_map().

1018 {
1019  if (TK_MAP != tb.kind) {
1020  return false;
1021  }
1022  return strongly_assignable(ta.map_type.key.common.type,
1023  tb.map_type.key.common.type) &&
1024  strongly_assignable(ta.map_type.element.common.type,
1025  tb.map_type.element.common.type);
1026 }
bool strongly_assignable(const TypeIdentifier &ta, const TypeIdentifier &tb) const
If types T1 and T2 are equivalent using the MINIMAL relation, or alternatively if T1 is-assignable-fr...
const TypeKind TK_MAP
Definition: TypeObject.h:250

◆ assignable_map() [2/2]

bool OpenDDS::XTypes::TypeAssignability::assignable_map ( const MinimalTypeObject ta,
const TypeIdentifier tb 
) const
private

The first type must be TK_MAP. The second type can be anything.

Definition at line 1032 of file TypeAssignability.cpp.

References OpenDDS::XTypes::MinimalTypeObject::alias_type, assignable_map(), OpenDDS::XTypes::MinimalAliasType::body, OpenDDS::XTypes::MinimalAliasBody::common, OpenDDS::XTypes::MinimalCollectionElement::common, OpenDDS::XTypes::EK_COMPLETE, OpenDDS::XTypes::EK_MINIMAL, OpenDDS::XTypes::MinimalMapType::element, OpenDDS::XTypes::MinimalMapType::key, OpenDDS::XTypes::TypeIdentifier::kind(), OpenDDS::XTypes::MinimalTypeObject::kind, lookup_minimal(), OpenDDS::XTypes::MinimalTypeObject::map_type, OpenDDS::XTypes::CommonAliasBody::related_type, strongly_assignable(), OpenDDS::XTypes::TI_PLAIN_MAP_LARGE, OpenDDS::XTypes::TI_PLAIN_MAP_SMALL, OpenDDS::XTypes::TK_ALIAS, OpenDDS::XTypes::TK_MAP, and OpenDDS::XTypes::CommonCollectionElement::type.

1034 {
1035  if (TI_PLAIN_MAP_SMALL == tb.kind()) {
1036  return strongly_assignable(ta.map_type.key.common.type,
1037  *tb.map_sdefn().key_identifier) &&
1038  strongly_assignable(ta.map_type.element.common.type,
1039  *tb.map_sdefn().element_identifier);
1040  } else if (TI_PLAIN_MAP_LARGE == tb.kind()) {
1041  return strongly_assignable(ta.map_type.key.common.type,
1042  *tb.map_ldefn().key_identifier) &&
1043  strongly_assignable(ta.map_type.element.common.type,
1044  *tb.map_ldefn().element_identifier);
1045  } else if (EK_MINIMAL == tb.kind()) {
1046  const MinimalTypeObject& tob = lookup_minimal(tb);
1047  if (TK_MAP == tob.kind) {
1048  return assignable_map(ta, tob);
1049  } else if (TK_ALIAS == tob.kind) {
1050  const TypeIdentifier& base = tob.alias_type.body.common.related_type;
1051  return assignable_map(ta, base);
1052  }
1053  } else if (EK_COMPLETE == tb.kind()) {
1054  // Assuming tb.kind of EK_COMPLETE is not supported
1055  return false;
1056  }
1057 
1058  return false;
1059 }
const MinimalTypeObject & lookup_minimal(const TypeIdentifier &ti) const
bool strongly_assignable(const TypeIdentifier &ta, const TypeIdentifier &tb) const
If types T1 and T2 are equivalent using the MINIMAL relation, or alternatively if T1 is-assignable-fr...
const EquivalenceKind EK_COMPLETE
Definition: TypeObject.h:206
const TypeIdentifierKind TI_PLAIN_MAP_LARGE
Definition: TypeObject.h:267
const TypeIdentifierKind TI_PLAIN_MAP_SMALL
Definition: TypeObject.h:266
const TypeKind TK_ALIAS
Definition: TypeObject.h:235
const EquivalenceKind EK_MINIMAL
Definition: TypeObject.h:205
bool assignable_map(const MinimalTypeObject &ta, const MinimalTypeObject &tb) const
The first type must be TK_MAP. The second type must not be TK_ALIAS.
const TypeKind TK_MAP
Definition: TypeObject.h:250

◆ assignable_plain_array() [1/2]

bool OpenDDS::XTypes::TypeAssignability::assignable_plain_array ( const TypeIdentifier ta,
const TypeIdentifier tb 
) const
private

The first type must be a plain array type. The second type can be anything.

Definition at line 1388 of file TypeAssignability.cpp.

References OpenDDS::XTypes::MinimalTypeObject::alias_type, OpenDDS::XTypes::MinimalAliasType::body, OpenDDS::XTypes::MinimalAliasBody::common, OpenDDS::XTypes::EK_COMPLETE, OpenDDS::XTypes::EK_MINIMAL, OpenDDS::XTypes::TypeIdentifier::kind(), OpenDDS::XTypes::MinimalTypeObject::kind, lookup_minimal(), OpenDDS::XTypes::Sequence< T >::members, OpenDDS::XTypes::CommonAliasBody::related_type, strongly_assignable(), OpenDDS::XTypes::TI_PLAIN_ARRAY_LARGE, OpenDDS::XTypes::TI_PLAIN_ARRAY_SMALL, OpenDDS::XTypes::TK_ALIAS, and OpenDDS::XTypes::TK_ARRAY.

Referenced by assignable(), and assignable_alias().

1390 {
1391  if (TI_PLAIN_ARRAY_SMALL == tb.kind()) {
1392  const Sequence<SBound>& bounds_b = tb.array_sdefn().array_bound_seq;
1393  if (TI_PLAIN_ARRAY_SMALL == ta.kind()) {
1394  const Sequence<SBound>& bounds_a = ta.array_sdefn().array_bound_seq;
1395  if (bounds_a.members.size() != bounds_b.members.size()) {
1396  return false;
1397  }
1398 
1399  for (size_t i = 0; i < bounds_a.members.size(); ++i) {
1400  if (bounds_a.members[i] != bounds_b.members[i]) {
1401  return false;
1402  }
1403  }
1404 
1405  return strongly_assignable(*ta.array_sdefn().element_identifier,
1406  *tb.array_sdefn().element_identifier);
1407  } else { // TI_PLAIN_ARRAY_LARGE
1408  const Sequence<LBound>& bounds_a = ta.array_ldefn().array_bound_seq;
1409  if (bounds_a.members.size() != bounds_b.members.size()) {
1410  return false;
1411  }
1412 
1413  for (size_t i = 0; i < bounds_a.members.size(); ++i) {
1414  if (bounds_a.members[i] != static_cast<LBound>(bounds_b.members[i])) {
1415  return false;
1416  }
1417  }
1418 
1419  return strongly_assignable(*ta.array_ldefn().element_identifier,
1420  *tb.array_sdefn().element_identifier);
1421  }
1422  } else if (TI_PLAIN_ARRAY_LARGE == tb.kind()) {
1423  const Sequence<LBound>& bounds_b = tb.array_ldefn().array_bound_seq;
1424  if (TI_PLAIN_ARRAY_SMALL == ta.kind()) {
1425  const Sequence<SBound>& bounds_a = ta.array_sdefn().array_bound_seq;
1426  if (bounds_a.members.size() != bounds_b.members.size()) {
1427  return false;
1428  }
1429 
1430  for (size_t i = 0; i < bounds_a.members.size(); ++i) {
1431  if (static_cast<LBound>(bounds_a.members[i]) != bounds_b.members[i]) {
1432  return false;
1433  }
1434  }
1435 
1436  return strongly_assignable(*ta.array_sdefn().element_identifier,
1437  *tb.array_ldefn().element_identifier);
1438  } else { // TI_PLAIN_ARRAY_LARGE
1439  const Sequence<LBound>& bounds_a = ta.array_ldefn().array_bound_seq;
1440  if (bounds_a.members.size() != bounds_b.members.size()) {
1441  return false;
1442  }
1443 
1444  for (size_t i = 0; i < bounds_a.members.size(); ++i) {
1445  if (bounds_a.members[i] != bounds_b.members[i]) {
1446  return false;
1447  }
1448  }
1449 
1450  return strongly_assignable(*ta.array_ldefn().element_identifier,
1451  *tb.array_ldefn().element_identifier);
1452  }
1453  } else if (EK_MINIMAL == tb.kind()) {
1454  const MinimalTypeObject& tob = lookup_minimal(tb);
1455  if (TK_ARRAY == tob.kind) {
1456  return assignable_plain_array(ta, tob);
1457  } else if (TK_ALIAS == tob.kind) {
1458  const TypeIdentifier& base = tob.alias_type.body.common.related_type;
1459  return assignable_plain_array(ta, base);
1460  }
1461  } else if (EK_COMPLETE == tb.kind()) {
1462  // Assuming tb.kind of EK_COMPLETE is not supported (similar to the way
1463  // assignability for plain sequences and plain maps are being handled)
1464  return false;
1465  }
1466 
1467  return false;
1468 }
const MinimalTypeObject & lookup_minimal(const TypeIdentifier &ti) const
bool strongly_assignable(const TypeIdentifier &ta, const TypeIdentifier &tb) const
If types T1 and T2 are equivalent using the MINIMAL relation, or alternatively if T1 is-assignable-fr...
bool assignable_plain_array(const TypeIdentifier &ta, const TypeIdentifier &tb) const
The first type must be a plain array type. The second type can be anything.
const EquivalenceKind EK_COMPLETE
Definition: TypeObject.h:206
const TypeIdentifierKind TI_PLAIN_ARRAY_LARGE
Definition: TypeObject.h:264
const TypeIdentifierKind TI_PLAIN_ARRAY_SMALL
Definition: TypeObject.h:263
const TypeKind TK_ALIAS
Definition: TypeObject.h:235
const EquivalenceKind EK_MINIMAL
Definition: TypeObject.h:205
const TypeKind TK_ARRAY
Definition: TypeObject.h:249

◆ assignable_plain_array() [2/2]

bool OpenDDS::XTypes::TypeAssignability::assignable_plain_array ( const TypeIdentifier ta,
const MinimalTypeObject tb 
) const
private

The first type must be a plain array type. The second type must not be TK_ALIAS.

Definition at line 1474 of file TypeAssignability.cpp.

References OpenDDS::XTypes::MinimalTypeObject::array_type, OpenDDS::XTypes::CommonArrayHeader::bound_seq, OpenDDS::XTypes::MinimalCollectionElement::common, OpenDDS::XTypes::MinimalArrayHeader::common, OpenDDS::XTypes::MinimalArrayType::element, OpenDDS::XTypes::MinimalArrayType::header, OpenDDS::XTypes::TypeIdentifier::kind(), OpenDDS::XTypes::MinimalTypeObject::kind, OpenDDS::XTypes::Sequence< T >::members, strongly_assignable(), OpenDDS::XTypes::TI_PLAIN_ARRAY_SMALL, OpenDDS::XTypes::TK_ARRAY, and OpenDDS::XTypes::CommonCollectionElement::type.

1476 {
1477  if (TK_ARRAY == tb.kind) {
1478  const Sequence<LBound>& bounds_b = tb.array_type.header.common.bound_seq;
1479  if (TI_PLAIN_ARRAY_SMALL == ta.kind()) {
1480  const Sequence<SBound>& bounds_a = ta.array_sdefn().array_bound_seq;
1481  if (bounds_a.members.size() != bounds_b.members.size()) {
1482  return false;
1483  }
1484 
1485  for (size_t i = 0; i < bounds_a.members.size(); ++i) {
1486  if (static_cast<LBound>(bounds_a.members[i]) != bounds_b.members[i]) {
1487  return false;
1488  }
1489  }
1490 
1491  return strongly_assignable(*ta.array_sdefn().element_identifier,
1492  tb.array_type.element.common.type);
1493  } else { // TI_PLAIN_ARRAY_LARGE
1494  const Sequence<LBound>& bounds_a = ta.array_ldefn().array_bound_seq;
1495  if (bounds_a.members.size() != bounds_b.members.size()) {
1496  return false;
1497  }
1498 
1499  for (size_t i = 0; i < bounds_a.members.size(); ++i) {
1500  if (bounds_a.members[i] != bounds_b.members[i]) {
1501  return false;
1502  }
1503  }
1504 
1505  return strongly_assignable(*ta.array_ldefn().element_identifier,
1506  tb.array_type.element.common.type);
1507  }
1508  }
1509 
1510  return false;
1511 }
bool strongly_assignable(const TypeIdentifier &ta, const TypeIdentifier &tb) const
If types T1 and T2 are equivalent using the MINIMAL relation, or alternatively if T1 is-assignable-fr...
const TypeIdentifierKind TI_PLAIN_ARRAY_SMALL
Definition: TypeObject.h:263
const TypeKind TK_ARRAY
Definition: TypeObject.h:249

◆ assignable_plain_map() [1/2]

bool OpenDDS::XTypes::TypeAssignability::assignable_plain_map ( const TypeIdentifier ta,
const TypeIdentifier tb 
) const
private

The first type must be a plain map type. The second type can be anything.

Definition at line 1517 of file TypeAssignability.cpp.

References OpenDDS::XTypes::MinimalTypeObject::alias_type, OpenDDS::XTypes::MinimalAliasType::body, OpenDDS::XTypes::MinimalAliasBody::common, OpenDDS::XTypes::EK_COMPLETE, OpenDDS::XTypes::EK_MINIMAL, OpenDDS::XTypes::TypeIdentifier::kind(), OpenDDS::XTypes::MinimalTypeObject::kind, lookup_minimal(), OpenDDS::XTypes::CommonAliasBody::related_type, strongly_assignable(), OpenDDS::XTypes::TI_PLAIN_MAP_LARGE, OpenDDS::XTypes::TI_PLAIN_MAP_SMALL, OpenDDS::XTypes::TK_ALIAS, and OpenDDS::XTypes::TK_MAP.

Referenced by assignable(), and assignable_alias().

1519 {
1520  if (TI_PLAIN_MAP_SMALL == tb.kind()) {
1521  if (TI_PLAIN_MAP_SMALL == ta.kind()) {
1522  return strongly_assignable(*ta.map_sdefn().key_identifier,
1523  *tb.map_sdefn().key_identifier) &&
1524  strongly_assignable(*ta.map_sdefn().element_identifier,
1525  *tb.map_sdefn().element_identifier);
1526  } else { // TI_PLAIN_MAP_LARGE
1527  return strongly_assignable(*ta.map_ldefn().key_identifier,
1528  *tb.map_sdefn().key_identifier) &&
1529  strongly_assignable(*ta.map_ldefn().element_identifier,
1530  *tb.map_sdefn().element_identifier);
1531  }
1532  } else if (TI_PLAIN_MAP_LARGE == tb.kind()) {
1533  if (TI_PLAIN_MAP_SMALL == ta.kind()) {
1534  return strongly_assignable(*ta.map_sdefn().key_identifier,
1535  *tb.map_ldefn().key_identifier) &&
1536  strongly_assignable(*ta.map_sdefn().element_identifier,
1537  *tb.map_ldefn().element_identifier);
1538  } else { // TI_PLAIN_MAP_LARGE
1539  return strongly_assignable(*ta.map_ldefn().key_identifier,
1540  *tb.map_ldefn().key_identifier) &&
1541  strongly_assignable(*ta.map_ldefn().element_identifier,
1542  *tb.map_ldefn().element_identifier);
1543  }
1544  } else if (EK_MINIMAL == tb.kind()) {
1545  const MinimalTypeObject& tob = lookup_minimal(tb);
1546  if (TK_MAP == tob.kind) {
1547  return assignable_plain_map(ta, tob);
1548  } else if (TK_ALIAS == tob.kind) {
1549  const TypeIdentifier& base = tob.alias_type.body.common.related_type;
1550  return assignable_plain_map(ta, base);
1551  }
1552  } else if (EK_COMPLETE == tb.kind()) {
1553  // Assuming tb.kind of EK_COMPLETE is not supported (similar to how
1554  // assignability for plain sequences and plain arrays are being handled)
1555  return false;
1556  }
1557 
1558  return false;
1559 }
const MinimalTypeObject & lookup_minimal(const TypeIdentifier &ti) const
bool strongly_assignable(const TypeIdentifier &ta, const TypeIdentifier &tb) const
If types T1 and T2 are equivalent using the MINIMAL relation, or alternatively if T1 is-assignable-fr...
const EquivalenceKind EK_COMPLETE
Definition: TypeObject.h:206
const TypeIdentifierKind TI_PLAIN_MAP_LARGE
Definition: TypeObject.h:267
const TypeIdentifierKind TI_PLAIN_MAP_SMALL
Definition: TypeObject.h:266
bool assignable_plain_map(const TypeIdentifier &ta, const TypeIdentifier &tb) const
The first type must be a plain map type. The second type can be anything.
const TypeKind TK_ALIAS
Definition: TypeObject.h:235
const EquivalenceKind EK_MINIMAL
Definition: TypeObject.h:205
const TypeKind TK_MAP
Definition: TypeObject.h:250

◆ assignable_plain_map() [2/2]

bool OpenDDS::XTypes::TypeAssignability::assignable_plain_map ( const TypeIdentifier ta,
const MinimalTypeObject tb 
) const
private

The first type must be a plain map type. The second type must not be TK_ALIAS.

Definition at line 1565 of file TypeAssignability.cpp.

References OpenDDS::XTypes::MinimalCollectionElement::common, OpenDDS::XTypes::MinimalMapType::element, OpenDDS::XTypes::MinimalMapType::key, OpenDDS::XTypes::TypeIdentifier::kind(), OpenDDS::XTypes::MinimalTypeObject::kind, OpenDDS::XTypes::MinimalTypeObject::map_type, strongly_assignable(), OpenDDS::XTypes::TI_PLAIN_MAP_SMALL, OpenDDS::XTypes::TK_MAP, and OpenDDS::XTypes::CommonCollectionElement::type.

1567 {
1568  if (TK_MAP == tb.kind) {
1569  if (TI_PLAIN_MAP_SMALL == ta.kind()) {
1570  return strongly_assignable(*ta.map_sdefn().key_identifier,
1571  tb.map_type.key.common.type) &&
1572  strongly_assignable(*ta.map_sdefn().element_identifier,
1573  tb.map_type.element.common.type);
1574  } else { // TI_PLAIN_MAP_LARGE
1575  return strongly_assignable(*ta.map_ldefn().key_identifier,
1576  tb.map_type.key.common.type) &&
1577  strongly_assignable(*ta.map_ldefn().element_identifier,
1578  tb.map_type.element.common.type);
1579  }
1580  }
1581 
1582  return false;
1583 }
bool strongly_assignable(const TypeIdentifier &ta, const TypeIdentifier &tb) const
If types T1 and T2 are equivalent using the MINIMAL relation, or alternatively if T1 is-assignable-fr...
const TypeIdentifierKind TI_PLAIN_MAP_SMALL
Definition: TypeObject.h:266
const TypeKind TK_MAP
Definition: TypeObject.h:250

◆ assignable_plain_sequence() [1/2]

bool OpenDDS::XTypes::TypeAssignability::assignable_plain_sequence ( const TypeIdentifier ta,
const TypeIdentifier tb 
) const
private

The first type must be a plain sequence type. The second type can be anything.

Definition at line 1326 of file TypeAssignability.cpp.

References OpenDDS::XTypes::MinimalTypeObject::alias_type, OpenDDS::XTypes::MinimalAliasType::body, OpenDDS::XTypes::MinimalAliasBody::common, OpenDDS::XTypes::EK_COMPLETE, OpenDDS::XTypes::EK_MINIMAL, OpenDDS::XTypes::TypeIdentifier::kind(), OpenDDS::XTypes::MinimalTypeObject::kind, lookup_minimal(), OpenDDS::XTypes::CommonAliasBody::related_type, strongly_assignable(), OpenDDS::XTypes::TI_PLAIN_SEQUENCE_LARGE, OpenDDS::XTypes::TI_PLAIN_SEQUENCE_SMALL, OpenDDS::XTypes::TK_ALIAS, and OpenDDS::XTypes::TK_SEQUENCE.

Referenced by assignable(), and assignable_alias().

1328 {
1329  if (TI_PLAIN_SEQUENCE_SMALL == tb.kind()) {
1330  if (TI_PLAIN_SEQUENCE_SMALL == ta.kind()) {
1331  return strongly_assignable(*ta.seq_sdefn().element_identifier,
1332  *tb.seq_sdefn().element_identifier);
1333  } else { // TI_PLAIN_SEQUENCE_LARGE
1334  return strongly_assignable(*ta.seq_ldefn().element_identifier,
1335  *tb.seq_sdefn().element_identifier);
1336  }
1337  } else if (TI_PLAIN_SEQUENCE_LARGE == tb.kind()) {
1338  if (TI_PLAIN_SEQUENCE_SMALL == ta.kind()) {
1339  return strongly_assignable(*ta.seq_sdefn().element_identifier,
1340  *tb.seq_ldefn().element_identifier);
1341  } else { // TI_PLAIN_SEQUENCE_LARGE
1342  return strongly_assignable(*ta.seq_ldefn().element_identifier,
1343  *tb.seq_ldefn().element_identifier);
1344  }
1345  } else if (EK_MINIMAL == tb.kind()) {
1346  const MinimalTypeObject& tob = lookup_minimal(tb);
1347  if (TK_SEQUENCE == tob.kind) {
1348  return assignable_plain_sequence(ta, tob);
1349  } else if (TK_ALIAS == tob.kind) {
1350  const TypeIdentifier& base = tob.alias_type.body.common.related_type;
1351  return assignable_plain_sequence(ta, base);
1352  }
1353  } else if (EK_COMPLETE == tb.kind()) {
1354  // Can tb.kind be EK_COMPLETE? More generally, can a MinimalTypeObject
1355  // depend on a TypeIdentifier that identifies a class of types which have
1356  // COMPLETE equivalence relation.
1357  // For now, assuming tb.kind of EK_COMPLETE is not supported.
1358  return false;
1359  }
1360 
1361  return false;
1362 }
const TypeKind TK_SEQUENCE
Definition: TypeObject.h:248
const TypeIdentifierKind TI_PLAIN_SEQUENCE_LARGE
Definition: TypeObject.h:261
const MinimalTypeObject & lookup_minimal(const TypeIdentifier &ti) const
bool strongly_assignable(const TypeIdentifier &ta, const TypeIdentifier &tb) const
If types T1 and T2 are equivalent using the MINIMAL relation, or alternatively if T1 is-assignable-fr...
const EquivalenceKind EK_COMPLETE
Definition: TypeObject.h:206
const TypeKind TK_ALIAS
Definition: TypeObject.h:235
const TypeIdentifierKind TI_PLAIN_SEQUENCE_SMALL
Definition: TypeObject.h:260
const EquivalenceKind EK_MINIMAL
Definition: TypeObject.h:205
bool assignable_plain_sequence(const TypeIdentifier &ta, const TypeIdentifier &tb) const
The first type must be a plain sequence type. The second type can be anything.

◆ assignable_plain_sequence() [2/2]

bool OpenDDS::XTypes::TypeAssignability::assignable_plain_sequence ( const TypeIdentifier ta,
const MinimalTypeObject tb 
) const
private

The first type must be a plain sequence type. The second type must not be TK_ALIAS.

Definition at line 1368 of file TypeAssignability.cpp.

References OpenDDS::XTypes::MinimalCollectionElement::common, OpenDDS::XTypes::MinimalSequenceType::element, OpenDDS::XTypes::TypeIdentifier::kind(), OpenDDS::XTypes::MinimalTypeObject::kind, OpenDDS::XTypes::MinimalTypeObject::sequence_type, strongly_assignable(), OpenDDS::XTypes::TI_PLAIN_SEQUENCE_SMALL, OpenDDS::XTypes::TK_SEQUENCE, and OpenDDS::XTypes::CommonCollectionElement::type.

1370 {
1371  if (TK_SEQUENCE == tb.kind) {
1372  if (TI_PLAIN_SEQUENCE_SMALL == ta.kind()) {
1373  return strongly_assignable(*ta.seq_sdefn().element_identifier,
1374  tb.sequence_type.element.common.type);
1375  } else { // TI_PLAIN_SEQUENCE_LARGE
1376  return strongly_assignable(*ta.seq_ldefn().element_identifier,
1377  tb.sequence_type.element.common.type);
1378  }
1379  }
1380 
1381  return false;
1382 }
const TypeKind TK_SEQUENCE
Definition: TypeObject.h:248
bool strongly_assignable(const TypeIdentifier &ta, const TypeIdentifier &tb) const
If types T1 and T2 are equivalent using the MINIMAL relation, or alternatively if T1 is-assignable-fr...
const TypeIdentifierKind TI_PLAIN_SEQUENCE_SMALL
Definition: TypeObject.h:260

◆ assignable_primitive() [1/2]

bool OpenDDS::XTypes::TypeAssignability::assignable_primitive ( const TypeIdentifier ta,
const TypeIdentifier tb 
) const
private

The first type must be a primitive type. The second type can be anything.

Definition at line 1233 of file TypeAssignability.cpp.

References OpenDDS::XTypes::MinimalTypeObject::alias_type, OpenDDS::XTypes::MinimalAliasType::body, OpenDDS::XTypes::MinimalAliasBody::common, OpenDDS::XTypes::EK_COMPLETE, OpenDDS::XTypes::EK_MINIMAL, OpenDDS::XTypes::TypeIdentifier::kind(), OpenDDS::XTypes::MinimalTypeObject::kind, lookup_minimal(), OpenDDS::XTypes::CommonAliasBody::related_type, OpenDDS::XTypes::TK_ALIAS, and OpenDDS::XTypes::TK_BITMASK.

Referenced by assignable(), and assignable_alias().

1235 {
1236  if (ta.kind() == tb.kind()) {
1237  return true;
1238  }
1239 
1240  if (EK_MINIMAL == tb.kind()) {
1241  const MinimalTypeObject& tob = lookup_minimal(tb);
1242  if (TK_BITMASK == tob.kind) {
1243  return assignable_primitive(ta, tob);
1244  } else if (TK_ALIAS == tob.kind) {
1245  const TypeIdentifier& base = tob.alias_type.body.common.related_type;
1246  return assignable_primitive(ta, base);
1247  }
1248  } else if (EK_COMPLETE == tb.kind()) {
1249  // Assuming tb.kind of EK_COMPLETE is not supported
1250  return false;
1251  }
1252 
1253  return false;
1254 }
const MinimalTypeObject & lookup_minimal(const TypeIdentifier &ti) const
const EquivalenceKind EK_COMPLETE
Definition: TypeObject.h:206
const TypeKind TK_BITMASK
Definition: TypeObject.h:239
const TypeKind TK_ALIAS
Definition: TypeObject.h:235
const EquivalenceKind EK_MINIMAL
Definition: TypeObject.h:205
bool assignable_primitive(const TypeIdentifier &ta, const TypeIdentifier &tb) const
The first type must be a primitive type. The second type can be anything.

◆ assignable_primitive() [2/2]

bool OpenDDS::XTypes::TypeAssignability::assignable_primitive ( const TypeIdentifier ta,
const MinimalTypeObject tb 
) const
private

The first type must be a primitive type. The second type must not be TK_ALIAS.

Definition at line 1260 of file TypeAssignability.cpp.

References OpenDDS::XTypes::CommonEnumeratedHeader::bit_bound, OpenDDS::XTypes::MinimalTypeObject::bitmask_type, OpenDDS::XTypes::MinimalEnumeratedHeader::common, OpenDDS::XTypes::MinimalBitmaskType::header, OpenDDS::XTypes::TypeIdentifier::kind(), OpenDDS::XTypes::MinimalTypeObject::kind, OpenDDS::XTypes::TK_BITMASK, OpenDDS::XTypes::TK_UINT16, OpenDDS::XTypes::TK_UINT32, OpenDDS::XTypes::TK_UINT64, and OpenDDS::XTypes::TK_UINT8.

1262 {
1263  if (TK_BITMASK != tb.kind ||
1264  !(TK_UINT8 == ta.kind() || TK_UINT16 == ta.kind() ||
1265  TK_UINT32 == ta.kind() || TK_UINT64 == ta.kind())) {
1266  return false;
1267  }
1268 
1269  BitBound bit_bound = tb.bitmask_type.header.common.bit_bound;
1270  if (TK_UINT8 == ta.kind()) {
1271  return 1 <= bit_bound && bit_bound <= 8;
1272  } else if (TK_UINT16 == ta.kind()) {
1273  return 9 <= bit_bound && bit_bound <= 16;
1274  } else if (TK_UINT32 == ta.kind()) {
1275  return 17 <= bit_bound && bit_bound <= 32;
1276  } else { // TK_UINT64
1277  return 33 <= bit_bound && bit_bound <= 64;
1278  }
1279 }
const TypeKind TK_UINT16
Definition: TypeObject.h:219
ACE_CDR::UShort BitBound
Definition: TypeObject.h:2478
const TypeKind TK_BITMASK
Definition: TypeObject.h:239
const TypeKind TK_UINT64
Definition: TypeObject.h:221
const TypeKind TK_UINT32
Definition: TypeObject.h:220
const TypeKind TK_UINT8
Definition: TypeObject.h:226

◆ assignable_sequence() [1/2]

bool OpenDDS::XTypes::TypeAssignability::assignable_sequence ( const MinimalTypeObject ta,
const MinimalTypeObject tb 
) const
private

The first type must be TK_SEQUENCE. The second type must not be TK_ALIAS.

Definition at line 895 of file TypeAssignability.cpp.

References OpenDDS::XTypes::MinimalCollectionElement::common, OpenDDS::XTypes::MinimalSequenceType::element, OpenDDS::XTypes::MinimalTypeObject::kind, OpenDDS::XTypes::MinimalTypeObject::sequence_type, strongly_assignable(), OpenDDS::XTypes::TK_SEQUENCE, and OpenDDS::XTypes::CommonCollectionElement::type.

Referenced by assignable(), assignable_alias(), and assignable_sequence().

897 {
898  if (TK_SEQUENCE != tb.kind) {
899  return false;
900  }
901  return strongly_assignable(ta.sequence_type.element.common.type,
902  tb.sequence_type.element.common.type);
903 }
const TypeKind TK_SEQUENCE
Definition: TypeObject.h:248
bool strongly_assignable(const TypeIdentifier &ta, const TypeIdentifier &tb) const
If types T1 and T2 are equivalent using the MINIMAL relation, or alternatively if T1 is-assignable-fr...

◆ assignable_sequence() [2/2]

bool OpenDDS::XTypes::TypeAssignability::assignable_sequence ( const MinimalTypeObject ta,
const TypeIdentifier tb 
) const
private

The first type must be TK_SEQUENCE. The second type can be anything.

Definition at line 909 of file TypeAssignability.cpp.

References OpenDDS::XTypes::MinimalTypeObject::alias_type, assignable_sequence(), OpenDDS::XTypes::MinimalAliasType::body, OpenDDS::XTypes::MinimalAliasBody::common, OpenDDS::XTypes::MinimalCollectionElement::common, OpenDDS::XTypes::EK_COMPLETE, OpenDDS::XTypes::EK_MINIMAL, OpenDDS::XTypes::MinimalSequenceType::element, OpenDDS::XTypes::TypeIdentifier::kind(), OpenDDS::XTypes::MinimalTypeObject::kind, lookup_minimal(), OpenDDS::XTypes::CommonAliasBody::related_type, OpenDDS::XTypes::MinimalTypeObject::sequence_type, strongly_assignable(), OpenDDS::XTypes::TI_PLAIN_SEQUENCE_LARGE, OpenDDS::XTypes::TI_PLAIN_SEQUENCE_SMALL, OpenDDS::XTypes::TK_ALIAS, OpenDDS::XTypes::TK_SEQUENCE, and OpenDDS::XTypes::CommonCollectionElement::type.

911 {
912  if (TI_PLAIN_SEQUENCE_SMALL == tb.kind()) {
913  return strongly_assignable(ta.sequence_type.element.common.type,
914  *tb.seq_sdefn().element_identifier);
915  } else if (TI_PLAIN_SEQUENCE_LARGE == tb.kind()) {
916  return strongly_assignable(ta.sequence_type.element.common.type,
917  *tb.seq_ldefn().element_identifier);
918  } else if (EK_MINIMAL == tb.kind()) {
919  const MinimalTypeObject& tob = lookup_minimal(tb);
920  if (TK_SEQUENCE == tob.kind) {
921  return assignable_sequence(ta, tob);
922  } else if (TK_ALIAS == tob.kind) {
923  const TypeIdentifier& base = tob.alias_type.body.common.related_type;
924  return assignable_sequence(ta, base);
925  }
926  } else if (EK_COMPLETE == tb.kind()) {
927  // Assuming tb.kind of EK_COMPLETE is not supported
928  return false;
929  }
930 
931  return false;
932 }
const TypeKind TK_SEQUENCE
Definition: TypeObject.h:248
const TypeIdentifierKind TI_PLAIN_SEQUENCE_LARGE
Definition: TypeObject.h:261
const MinimalTypeObject & lookup_minimal(const TypeIdentifier &ti) const
bool strongly_assignable(const TypeIdentifier &ta, const TypeIdentifier &tb) const
If types T1 and T2 are equivalent using the MINIMAL relation, or alternatively if T1 is-assignable-fr...
const EquivalenceKind EK_COMPLETE
Definition: TypeObject.h:206
bool assignable_sequence(const MinimalTypeObject &ta, const MinimalTypeObject &tb) const
The first type must be TK_SEQUENCE. The second type must not be TK_ALIAS.
const TypeKind TK_ALIAS
Definition: TypeObject.h:235
const TypeIdentifierKind TI_PLAIN_SEQUENCE_SMALL
Definition: TypeObject.h:260
const EquivalenceKind EK_MINIMAL
Definition: TypeObject.h:205

◆ assignable_string() [1/2]

bool OpenDDS::XTypes::TypeAssignability::assignable_string ( const TypeIdentifier ta,
const TypeIdentifier tb 
) const
private

The first type must be a string type. The second type can be anything.

Definition at line 1285 of file TypeAssignability.cpp.

References OpenDDS::XTypes::MinimalTypeObject::alias_type, OpenDDS::XTypes::MinimalAliasType::body, OpenDDS::XTypes::MinimalAliasBody::common, OpenDDS::XTypes::EK_COMPLETE, OpenDDS::XTypes::EK_MINIMAL, OpenDDS::XTypes::TypeIdentifier::kind(), OpenDDS::XTypes::MinimalTypeObject::kind, lookup_minimal(), OpenDDS::XTypes::CommonAliasBody::related_type, OpenDDS::XTypes::TI_STRING16_LARGE, OpenDDS::XTypes::TI_STRING16_SMALL, OpenDDS::XTypes::TI_STRING8_LARGE, OpenDDS::XTypes::TI_STRING8_SMALL, and OpenDDS::XTypes::TK_ALIAS.

Referenced by assignable(), and assignable_alias().

1287 {
1288  if (TI_STRING8_SMALL == tb.kind() || TI_STRING8_LARGE == tb.kind()) {
1289  if (TI_STRING8_SMALL == ta.kind() || TI_STRING8_LARGE == ta.kind()) {
1290  return true;
1291  }
1292  } else if (TI_STRING16_SMALL == tb.kind() || TI_STRING16_LARGE == tb.kind()) {
1293  if (TI_STRING16_SMALL == ta.kind() || TI_STRING16_LARGE == ta.kind()) {
1294  return true;
1295  }
1296  } else if (EK_MINIMAL == tb.kind()) {
1297  const MinimalTypeObject& tob = lookup_minimal(tb);
1298  if (TK_ALIAS == tob.kind) {
1299  const TypeIdentifier& base = tob.alias_type.body.common.related_type;
1300  return assignable_string(ta, base);
1301  }
1302  } else if (EK_COMPLETE == tb.kind()) {
1303  // Assuming tb.kind of EK_COMPLETE is not supported
1304  return false;
1305  }
1306 
1307  return false;
1308 }
const TypeIdentifierKind TI_STRING8_LARGE
Definition: TypeObject.h:256
const MinimalTypeObject & lookup_minimal(const TypeIdentifier &ti) const
const TypeIdentifierKind TI_STRING16_LARGE
Definition: TypeObject.h:258
const TypeIdentifierKind TI_STRING8_SMALL
Definition: TypeObject.h:255
const EquivalenceKind EK_COMPLETE
Definition: TypeObject.h:206
const TypeKind TK_ALIAS
Definition: TypeObject.h:235
const EquivalenceKind EK_MINIMAL
Definition: TypeObject.h:205
const TypeIdentifierKind TI_STRING16_SMALL
Definition: TypeObject.h:257
bool assignable_string(const TypeIdentifier &ta, const TypeIdentifier &tb) const
The first type must be a string type. The second type can be anything.

◆ assignable_string() [2/2]

bool OpenDDS::XTypes::TypeAssignability::assignable_string ( const TypeIdentifier ta,
const MinimalTypeObject tb 
) const
private

The first type must be a string type. The second type must not be TK_ALIAS.

Definition at line 1314 of file TypeAssignability.cpp.

1316 {
1317  // The second type cannot be string since string types do not have
1318  // type object. Thus the first type is not assignable from the second type.
1319  return false;
1320 }

◆ assignable_struct() [1/2]

bool OpenDDS::XTypes::TypeAssignability::assignable_struct ( const MinimalTypeObject ta,
const MinimalTypeObject tb 
) const
private

The first type must be TK_STRUCTURE. The second type must not be TK_ALIAS.

Definition at line 317 of file TypeAssignability.cpp.

References assignable(), OpenDDS::XTypes::EK_MINIMAL, erase_key(), get_base_type(), get_map_bound(), get_sequence_bound(), get_string_bound(), get_struct_member(), get_union_member(), hold_key(), OpenDDS::XTypes::TypeConsistencyAttributes::ignore_member_names, OpenDDS::XTypes::IS_APPENDABLE, OpenDDS::XTypes::IS_FINAL, OpenDDS::XTypes::IS_KEY, OpenDDS::XTypes::IS_MUST_UNDERSTAND, OpenDDS::XTypes::IS_MUTABLE, OpenDDS::XTypes::IS_OPTIONAL, OpenDDS::XTypes::TypeIdentifier::kind(), OpenDDS::XTypes::MinimalTypeObject::kind, OpenDDS::XTypes::Sequence< T >::length(), lookup_minimal(), OpenDDS::XTypes::CommonStructMember::member_flags, OpenDDS::XTypes::MinimalStructType::member_seq, OpenDDS::XTypes::MinimalUnionType::member_seq, OpenDDS::XTypes::CommonStructMember::member_type_id, strongly_assignable(), OpenDDS::XTypes::MinimalStructType::struct_flags, struct_rule_enum_key(), OpenDDS::XTypes::MinimalTypeObject::struct_type, OpenDDS::XTypes::TK_ALIAS, OpenDDS::XTypes::TK_ENUM, OpenDDS::XTypes::TK_STRUCTURE, OpenDDS::XTypes::TK_UNION, type_consistency_, and OpenDDS::XTypes::MinimalTypeObject::union_type.

Referenced by assignable(), assignable_alias(), and assignable_struct().

319 {
320  if (TK_STRUCTURE != tb.kind) {
321  return false;
322  }
323 
324  // Extensibility kind must match
325  const TypeFlag extensibility_mask = IS_FINAL | IS_APPENDABLE | IS_MUTABLE;
326  const ACE_CDR::UShort a_exten = ta.struct_type.struct_flags & extensibility_mask;
327  if (a_exten != (tb.struct_type.struct_flags & extensibility_mask)) {
328  return false;
329  }
330 
331  // If T1 is appendable, then members with the same member_index have the
332  // same member ID, the same setting for the 'optional' attribute and the
333  // T1 member type is strongly assignable from the T2 member type.
334  // If T1 is final, then they meet the same condition as for T1 being
335  // appendable and in addition T1 and T2 have the same set of member IDs.
336  if (IS_FINAL == a_exten &&
337  ta.struct_type.member_seq.length() != tb.struct_type.member_seq.length()) {
338  return false;
339  }
340  if (IS_APPENDABLE == a_exten || IS_FINAL == a_exten) {
341  const unsigned num_members = (std::min)(ta.struct_type.member_seq.length(),
342  tb.struct_type.member_seq.length());
343  for (unsigned i = 0; i < num_members; ++i) {
344  if (ta.struct_type.member_seq[i].common.member_id !=
345  tb.struct_type.member_seq[i].common.member_id ||
346  (ta.struct_type.member_seq[i].common.member_flags & IS_OPTIONAL) !=
347  (tb.struct_type.member_seq[i].common.member_flags & IS_OPTIONAL) ||
348  !strongly_assignable(ta.struct_type.member_seq[i].common.member_type_id,
349  tb.struct_type.member_seq[i].common.member_type_id)) {
350  return false;
351  }
352  }
353  }
354 
355  // Any members in T1 and T2 that have the same name also have
356  // the same ID, and vice versa
357  MatchedSet matched_members;
358  for (unsigned i = 0; i < ta.struct_type.member_seq.length(); ++i) {
359  MemberId id_a = ta.struct_type.member_seq[i].common.member_id;
360  const NameHash& h_a = ta.struct_type.member_seq[i].detail.name_hash;
361  ACE_CDR::ULong name_a = (h_a[0] << 24) | (h_a[1] << 16) | (h_a[2] << 8) | (h_a[3]);
362  for (unsigned j = 0; j < tb.struct_type.member_seq.length(); ++j) {
363  MemberId id_b = tb.struct_type.member_seq[j].common.member_id;
364  const NameHash& h_b = tb.struct_type.member_seq[j].detail.name_hash;
365  ACE_CDR::ULong name_b = (h_b[0] << 24) | (h_b[1] << 16) | (h_b[2] << 8) | (h_b[3]);
366 
368  if ((name_a == name_b && id_a != id_b) || (id_a == id_b && name_a != name_b)) {
369  return false;
370  } else if (name_a == name_b && id_a == id_b) {
371  matched_members.push_back(std::make_pair(&ta.struct_type.member_seq[i],
372  &tb.struct_type.member_seq[j]));
373  break;
374  }
375  } else if (id_a == id_b) {
376  matched_members.push_back(std::make_pair(&ta.struct_type.member_seq[i],
377  &tb.struct_type.member_seq[j]));
378  break;
379  }
380  }
381  }
382 
383  // There is at least one member m1 of T1 and one corresponding member
384  // m2 of T2 such that m1.id == m2.id
385  if (matched_members.size() == 0) {
386  return false;
387  }
388 
389  // For any member m2 of T2, if there is a member m1 of T1 with the same
390  // ID, then the type KeyErased(m1.type) is-assignable-from the type
391  // KeyErased(m2.type).
392  // For any non-aggregated type T, we consider that KeyErased(T) = T
393  // (whereas the spec only defines KeyErased for aggregated types).
394  // Consequently, this rule applies to any pair of members m2 of T2 and
395  // m1 of T1 with the same ID.
396  for (size_t i = 0; i < matched_members.size(); ++i) {
397  const CommonStructMember& member = matched_members[i].second->common;
398  const MinimalTypeObject* toa = 0;
399  const MinimalTypeObject* tob = 0;
400  bool aggregated_type_matched = false;
401  if (get_struct_member(tob, member)) {
402  if (!get_struct_member(toa, matched_members[i].first->common)) {
403  return false;
404  }
405  aggregated_type_matched = true;
406  } else if (get_union_member(tob, member)) {
407  if (!get_union_member(toa, matched_members[i].first->common)) {
408  return false;
409  }
410  aggregated_type_matched = true;
411  }
412 
413  if (aggregated_type_matched) {
414  MinimalTypeObject key_erased_a = *toa, key_erased_b = *tob;
415  erase_key(key_erased_a);
416  erase_key(key_erased_b);
417  if (!assignable(TypeObject(key_erased_a), TypeObject(key_erased_b))) {
418  return false;
419  }
420  } else if (!assignable(matched_members[i].first->common.member_type_id,
421  matched_members[i].second->common.member_type_id)) {
422  return false;
423  }
424  }
425 
426  // Members for which both optional is false and must_understand is true in
427  // either T1 or T2 appear in both T1 and T2.
428  // Members marked as key in either T1 or T2 appear in both T1 and T2.
429  for (unsigned i = 0; i < ta.struct_type.member_seq.length(); ++i) {
430  const MemberFlag& flags = ta.struct_type.member_seq[i].common.member_flags;
431  MemberId id = ta.struct_type.member_seq[i].common.member_id;
432  bool found = false;
433  if ((flags & (IS_OPTIONAL | IS_MUST_UNDERSTAND)) == IS_MUST_UNDERSTAND) {
434  for (size_t j = 0; j < matched_members.size(); ++j) {
435  if (id == matched_members[j].first->common.member_id) {
436  found = true;
437  break;
438  }
439  }
440  if (!found) {
441  return false;
442  }
443  }
444 
445  found = false;
446  if ((flags & IS_KEY) == IS_KEY) {
447  for (size_t j = 0; j < matched_members.size(); ++j) {
448  if (id == matched_members[j].first->common.member_id) {
449  found = true;
450  break;
451  }
452  }
453  if (!found) {
454  return false;
455  }
456  }
457  }
458 
459  for (unsigned i = 0; i < tb.struct_type.member_seq.length(); ++i) {
460  const MemberFlag& flags = tb.struct_type.member_seq[i].common.member_flags;
461  MemberId id = tb.struct_type.member_seq[i].common.member_id;
462  bool found = false;
463  if ((flags & (IS_OPTIONAL | IS_MUST_UNDERSTAND)) == IS_MUST_UNDERSTAND) {
464  for (size_t j = 0; j < matched_members.size(); ++j) {
465  if (id == matched_members[j].second->common.member_id) {
466  found = true;
467  break;
468  }
469  }
470  if (!found) {
471  return false;
472  }
473  }
474 
475  found = false;
476  if ((flags & IS_KEY) == IS_KEY) {
477  for (size_t j = 0; j < matched_members.size(); ++j) {
478  if (id == matched_members[j].second->common.member_id) {
479  found = true;
480  break;
481  }
482  }
483  if (!found) {
484  return false;
485  }
486  }
487  }
488 
489  // For any string key member m2 in T2, the m1 member of T1 with the
490  // same member ID verifies m1.type.length >= m2.type.length
491  for (size_t i = 0; i < matched_members.size(); ++i) {
492  const CommonStructMember& member = matched_members[i].second->common;
493  MemberFlag flags = member.member_flags;
494  LBound bound_a, bound_b;
495  if ((flags & IS_KEY) == IS_KEY && get_string_bound(bound_b, member)) {
496  if (!get_string_bound(bound_a, matched_members[i].first->common)) {
497  return false;
498  }
499  if (bound_a < bound_b) {
500  return false;
501  }
502  }
503  }
504 
505  // For any enumerated key member m2 in T2, the m1 member of T1 with
506  // the same member ID verifies that all literals in m2.type appear as
507  // literals in m1.type
508  for (size_t i = 0; i < matched_members.size(); ++i) {
509  const CommonStructMember& member = matched_members[i].second->common;
510  MemberFlag flags = member.member_flags;
511  if ((flags & IS_KEY) == IS_KEY &&
512  EK_MINIMAL == member.member_type_id.kind()) {
513  const MinimalTypeObject& tob = lookup_minimal(member.member_type_id);
514  if (TK_ENUM == tob.kind) {
515  if (!struct_rule_enum_key(tob, matched_members[i].first->common)) {
516  return false;
517  }
518  } else if (TK_ALIAS == tob.kind) {
519  const TypeIdentifier& base_b = get_base_type(tob);
520  if (EK_MINIMAL == base_b.kind()) {
521  const MinimalTypeObject& base_obj_b = lookup_minimal(base_b);
522  if (TK_ENUM == base_obj_b.kind &&
523  !struct_rule_enum_key(base_obj_b, matched_members[i].first->common)) {
524  return false;
525  }
526  }
527  }
528  }
529  }
530 
531  // For any sequence or map key member m2 in T2, the m1 member of T1
532  // with the same member ID verifies m1.type.length >= m2.type.length
533  for (size_t i = 0; i < matched_members.size(); ++i) {
534  const CommonStructMember& member = matched_members[i].second->common;
535  MemberFlag flags = member.member_flags;
536  LBound bound_a, bound_b;
537  if ((flags & IS_KEY) == IS_KEY) {
538  if (get_sequence_bound(bound_b, member)) {
539  if (!get_sequence_bound(bound_a, matched_members[i].first->common)) {
540  return false;
541  }
542  if (bound_a < bound_b) {
543  return false;
544  }
545  } else if (get_map_bound(bound_b, member)) {
546  if (!get_map_bound(bound_a, matched_members[i].first->common)) {
547  return false;
548  }
549  if (bound_a < bound_b) {
550  return false;
551  }
552  }
553  }
554  }
555 
556  // For any structure or union key member m2 in T2, the m1 member
557  // of T1 with the same member ID verifies that KeyHolder(m1.type)
558  // is-assignable-from KeyHolder(m2.type)
559  for (size_t i = 0; i < matched_members.size(); ++i) {
560  const CommonStructMember& member = matched_members[i].second->common;
561  MemberFlag flags = member.member_flags;
562  if ((flags & IS_KEY) == IS_KEY) {
563  const MinimalTypeObject* toa = 0;
564  const MinimalTypeObject* tob = 0;
565  bool type_matched = false;
566  if (get_struct_member(tob, member)) {
567  if (!get_struct_member(toa, matched_members[i].first->common)) {
568  return false;
569  }
570  type_matched = true;
571  } else if (get_union_member(tob, member)) {
572  if (!get_union_member(toa, matched_members[i].first->common)) {
573  return false;
574  }
575  type_matched = true;
576  }
577 
578  if (type_matched) {
579  MinimalTypeObject key_holder_a = *toa, key_holder_b = *tob;
580  hold_key(key_holder_a);
581  hold_key(key_holder_b);
582  if (!assignable(TypeObject(key_holder_a), TypeObject(key_holder_b))) {
583  return false;
584  }
585 
586  // For any union key member m2 in T2, the m1 member of T1 with the
587  // same ID verifies that: for every discriminator value of m2.type
588  // that selects a member m22 in m2.type, the discriminator value
589  // selects a member m11 in m1.type that verifies KeyHolder(m11.type)
590  // is-assignable-from KeyHolder(m22.type)
591  if (TK_UNION == tob->kind) {
592  const MinimalUnionMemberSeq& mseq_a = toa->union_type.member_seq;
593  const MinimalUnionMemberSeq& mseq_b = tob->union_type.member_seq;
594  for (unsigned j = 0; j < mseq_b.length(); ++j) {
595  const UnionCaseLabelSeq& labels_b = mseq_b[j].common.label_seq;
596  for (unsigned k = 0; k < mseq_a.length(); ++k) {
597  const UnionCaseLabelSeq& labels_a = mseq_a[k].common.label_seq;
598  bool matched = false;
599  for (unsigned p = 0; p < labels_b.length(); ++p) {
600  for (unsigned q = 0; q < labels_a.length(); ++q) {
601  if (labels_b[p] == labels_a[q]) {
602  const TypeIdentifier& tib = mseq_b[j].common.type_id;
603  const TypeIdentifier& tia = mseq_a[k].common.type_id;
604  MinimalTypeObject kh_a, kh_b;
605  bool ret_b = hold_key(tib, kh_b);
606  bool ret_a = hold_key(tia, kh_a);
607  if ((ret_a && ret_b && !assignable(TypeObject(kh_a), TypeObject(kh_b))) ||
608  (ret_a && !ret_b && !assignable(TypeObject(kh_a), tib)) ||
609  (!ret_a && ret_b && !assignable(tia, TypeObject(kh_b))) ||
610  (!ret_a && !ret_b && !assignable(tia, tib))) {
611  return false;
612  }
613  matched = true;
614  break;
615  }
616  } // labels_a
617  if (matched) break;
618  } // labels_b
619  } // mseq_a
620  } // mseq_b
621  }
622  }
623  } // IS_KEY
624  }
625 
626  return true;
627 }
ACE_CDR::ULong MemberId
Definition: TypeObject.h:910
const TypeFlag IS_MUTABLE
Definition: TypeObject.h:402
const TypeKind TK_UNION
Definition: TypeObject.h:244
bool get_sequence_bound(LBound &b, const CommonStructMember &m) const
Check whether a struct member is of sequence type and if so compute its bound into the first argument...
TypeConsistencyAttributes type_consistency_
const MinimalTypeObject & lookup_minimal(const TypeIdentifier &ti) const
bool get_union_member(const MinimalTypeObject *&ret, const CommonStructMember &m) const
Check if the second argument is of a union type and if so return its type object as the first argumen...
const MemberFlag IS_MUST_UNDERSTAND
Definition: TypeObject.h:374
void erase_key(MinimalTypeObject &type) const
Key-Erased type of an aggregated type T (struct or union) is constructed from T by removing the key d...
const TypeIdentifier & get_base_type(const MinimalTypeObject &type) const
The input must be of type TK_ALIAS Return the non-alias base type identifier of the input...
bool strongly_assignable(const TypeIdentifier &ta, const TypeIdentifier &tb) const
If types T1 and T2 are equivalent using the MINIMAL relation, or alternatively if T1 is-assignable-fr...
bool get_struct_member(const MinimalTypeObject *&ret, const CommonStructMember &m) const
Check if the second argument is of a struct type and if so return its type object as the first argume...
ACE_CDR::UShort MemberFlag
Definition: TypeObject.h:368
const MemberFlag IS_KEY
Definition: TypeObject.h:375
ACE_UINT16 UShort
const TypeFlag IS_FINAL
Definition: TypeObject.h:400
bool get_map_bound(LBound &b, const CommonStructMember &m) const
Check whether a struct member is of map type and if so compute its bound into the first argument...
bool struct_rule_enum_key(const MinimalTypeObject &tb, const CommonStructMember &ma) const
The first argument must be TK_ENUM and is the type object of a key member of the containing struct...
ACE_UINT32 ULong
const TypeKind TK_STRUCTURE
Definition: TypeObject.h:243
bool assignable(const TypeObject &ta, const TypeObject &tb) const
Both input type objects must be minimal.
void hold_key(MinimalTypeObject &type) const
Key-Holder type of an aggregated type T (struct or union) is constructed from T (sub-clause 7...
ACE_CDR::UShort TypeFlag
Definition: TypeObject.h:399
bool get_string_bound(LBound &b, const CommonStructMember &m) const
Check whether the input struct member is of string type and if so compute its bound into the first ar...
const MemberFlag IS_OPTIONAL
Definition: TypeObject.h:373
const TypeKind TK_ALIAS
Definition: TypeObject.h:235
const TypeKind TK_ENUM
Definition: TypeObject.h:238
const TypeFlag IS_APPENDABLE
Definition: TypeObject.h:401
Sequence< ACE_CDR::Long > UnionCaseLabelSeq
Definition: TypeObject.h:1534
const EquivalenceKind EK_MINIMAL
Definition: TypeObject.h:205
ACE_CDR::ULong LBound
Definition: TypeObject.h:312
Sequence< MinimalUnionMember > MinimalUnionMemberSeq
Definition: TypeObject.h:1628
ACE_CDR::Octet NameHash[4]
Definition: TypeObject.h:296

◆ assignable_struct() [2/2]

bool OpenDDS::XTypes::TypeAssignability::assignable_struct ( const MinimalTypeObject ta,
const TypeIdentifier tb 
) const
private

The first type must be TK_STRUCTURE. The second type can be anything.

Definition at line 633 of file TypeAssignability.cpp.

References OpenDDS::XTypes::MinimalTypeObject::alias_type, assignable_struct(), OpenDDS::XTypes::MinimalAliasType::body, OpenDDS::XTypes::MinimalAliasBody::common, OpenDDS::XTypes::EK_COMPLETE, OpenDDS::XTypes::EK_MINIMAL, OpenDDS::XTypes::TypeIdentifier::kind(), OpenDDS::XTypes::MinimalTypeObject::kind, lookup_minimal(), OpenDDS::XTypes::CommonAliasBody::related_type, OpenDDS::XTypes::TK_ALIAS, and OpenDDS::XTypes::TK_STRUCTURE.

635 {
636  if (EK_MINIMAL == tb.kind()) {
637  const MinimalTypeObject& tob = lookup_minimal(tb);
638  if (TK_STRUCTURE == tob.kind) {
639  return assignable_struct(ta, tob);
640  } else if (TK_ALIAS == tob.kind) {
641  const TypeIdentifier& base = tob.alias_type.body.common.related_type;
642  return assignable_struct(ta, base);
643  }
644  } else if (EK_COMPLETE == tb.kind()) {
645  // Assuming tb.kind of EK_COMPLETE is not supported
646  return false;
647  }
648 
649  return false;
650 }
const MinimalTypeObject & lookup_minimal(const TypeIdentifier &ti) const
bool assignable_struct(const MinimalTypeObject &ta, const MinimalTypeObject &tb) const
The first type must be TK_STRUCTURE. The second type must not be TK_ALIAS.
const EquivalenceKind EK_COMPLETE
Definition: TypeObject.h:206
const TypeKind TK_STRUCTURE
Definition: TypeObject.h:243
const TypeKind TK_ALIAS
Definition: TypeObject.h:235
const EquivalenceKind EK_MINIMAL
Definition: TypeObject.h:205

◆ assignable_union() [1/2]

bool OpenDDS::XTypes::TypeAssignability::assignable_union ( const MinimalTypeObject ta,
const MinimalTypeObject tb 
) const
private

The first type must be TK_UNION. The second type must not be TK_ALIAS.

Definition at line 656 of file TypeAssignability.cpp.

References assignable(), OpenDDS::XTypes::MinimalDiscriminatorMember::common, OpenDDS::XTypes::MinimalUnionType::discriminator, OpenDDS::XTypes::TypeConsistencyAttributes::ignore_member_names, OpenDDS::XTypes::IS_APPENDABLE, OpenDDS::XTypes::IS_DEFAULT, OpenDDS::XTypes::IS_FINAL, OpenDDS::XTypes::IS_KEY, OpenDDS::XTypes::IS_MUTABLE, OpenDDS::XTypes::MinimalTypeObject::kind, OpenDDS::XTypes::Sequence< T >::length(), OpenDDS::XTypes::CommonDiscriminatorMember::member_flags, OpenDDS::XTypes::MinimalUnionType::member_seq, OpenDDS::XTypes::Sequence< T >::members, name, OpenDDS::XTypes::OPENDDS_MAP(), OpenDDS::XTypes::OPENDDS_SET(), strongly_assignable(), OpenDDS::XTypes::TK_UNION, type_consistency_, OpenDDS::XTypes::CommonDiscriminatorMember::type_id, OpenDDS::XTypes::MinimalUnionType::union_flags, and OpenDDS::XTypes::MinimalTypeObject::union_type.

Referenced by assignable(), assignable_alias(), and assignable_union().

658 {
659  if (TK_UNION != tb.kind) {
660  return false;
661  }
662 
663  // Extensibility kind must match
664  const TypeFlag extensibility_mask = IS_FINAL | IS_APPENDABLE | IS_MUTABLE;
665  if ((ta.union_type.union_flags & extensibility_mask) !=
666  (tb.union_type.union_flags & extensibility_mask)) {
667  return false;
668  }
669 
670  OPENDDS_SET(ACE_CDR::Long) labels_set_a;
671  for (unsigned i = 0; i < ta.union_type.member_seq.length(); ++i) {
672  const UnionCaseLabelSeq& labels_a = ta.union_type.member_seq[i].common.label_seq;
673  labels_set_a.insert(labels_a.members.begin(), labels_a.members.end());
674  }
675 
676  // If extensibility is final, then the set of labels must be identical.
677  // Assuming labels are mapped to values identically in both input types.
678  if ((ta.union_type.union_flags & extensibility_mask) == IS_FINAL) {
679  for (unsigned i = 0; i < tb.union_type.member_seq.length(); ++i) {
680  const UnionCaseLabelSeq& labels_b = tb.union_type.member_seq[i].common.label_seq;
681  for (unsigned j = 0; j < labels_b.length(); ++j) {
682  if (labels_set_a.find(labels_b.members[j]) == labels_set_a.end()) {
683  return false;
684  }
685  labels_set_a.erase(labels_b.members[j]);
686  }
687  }
688  if (labels_set_a.size() > 0) {
689  return false;
690  }
691  } else { // Must have at least one common label other than the default
692  // This implementation assumes that the default member has IS_DEFAULT
693  // flag turned on, but the label "default" does not map into a numeric
694  // value for storing on the member's UnionCaseLabelSeq. Instead, only
695  // the other labels, if any, for this default members will have their
696  // numeric values stored in its UnionCaseLabelSeq.
697  bool found = false;
698  for (unsigned i = 0; i < tb.union_type.member_seq.length(); ++i) {
699  const UnionCaseLabelSeq& labels_b = tb.union_type.member_seq[i].common.label_seq;
700  for (unsigned j = 0; j < labels_b.length(); ++j) {
701  if (labels_set_a.find(labels_b[j]) != labels_set_a.end()) {
702  found = true;
703  break;
704  }
705  }
706  if (found) break;
707  }
708  if (!found) {
709  return false;
710  }
711  }
712 
713  // Discriminator type must be one of these: (i) non-float primitive types,
714  // or (ii) enumerated types, or (iii) an alias type that resolves to
715  // one of the above two type kinds
716  const TypeIdentifier& tia = ta.union_type.discriminator.common.type_id;
717  const TypeIdentifier& tib = tb.union_type.discriminator.common.type_id;
718  if (!strongly_assignable(tia, tib)) {
719  return false;
720  }
721 
722  // Both discriminators are keys or neither are keys
723  const MemberFlag& flags_a = ta.union_type.discriminator.common.member_flags;
724  const MemberFlag& flags_b = tb.union_type.discriminator.common.member_flags;
725  if ((((flags_a & IS_KEY) == IS_KEY) && ((flags_b & IS_KEY) != IS_KEY)) ||
726  (((flags_a & IS_KEY) != IS_KEY) && ((flags_b & IS_KEY) == IS_KEY))) {
727  return false;
728  }
729 
730  // Members with the same ID must have the same name, and vice versa
732  OPENDDS_MAP(MemberId, ACE_CDR::ULong) id_to_name_a;
733  OPENDDS_MAP(ACE_CDR::ULong, MemberId) name_to_id_a;
734  for (unsigned i = 0; i < ta.union_type.member_seq.length(); ++i) {
735  MemberId id = ta.union_type.member_seq[i].common.member_id;
736  const NameHash& h = ta.union_type.member_seq[i].detail.name_hash;
737  ACE_CDR::ULong name = (h[0] << 24) | (h[1] << 16) | (h[2] << 8) | (h[3]);
738  id_to_name_a[id] = name;
739  name_to_id_a[name] = id;
740  }
741 
742  for (unsigned i = 0; i < tb.union_type.member_seq.length(); ++i) {
743  MemberId id = tb.union_type.member_seq[i].common.member_id;
744  const NameHash& h = tb.union_type.member_seq[i].detail.name_hash;
745  ACE_CDR::ULong name = (h[0] << 24) | (h[1] << 16) | (h[2] << 8) | (h[3]);
746  if (id_to_name_a.find(id) != id_to_name_a.end() &&
747  id_to_name_a[id] != name) {
748  return false;
749  }
750 
751  if (name_to_id_a.find(name) != name_to_id_a.end() &&
752  name_to_id_a[name] != id) {
753  return false;
754  }
755  }
756  }
757 
758  // For all non-default labels in T2 that select some member in T1,
759  // the type of the selected member in T1 is assignable from the
760  // type of the T2 member
761  for (unsigned i = 0; i < tb.union_type.member_seq.length(); ++i) {
762  const UnionCaseLabelSeq& label_seq_b = tb.union_type.member_seq[i].common.label_seq;
763  for (unsigned j = 0; j < ta.union_type.member_seq.length(); ++j) {
764  // Consider a case when tb has multiple labels for a member, e.g.,
765  // "LABEL1" and "LABEL2" are associated with a member of type MemberB,
766  // and ta has two members, one has label "LABEL1" and
767  // type MemberA1, and the other has label "LABEL2" and
768  // type MemberA2. There are two possible ways to check assignability:
769  // (i) check whether BOTH MemberA1 and MemberA2 are assignable from
770  // MemberB since labels for MemberB match the labels of both MemberA1
771  // and MemberA2 (i.e., all must be assignable), or (ii) check EITHER
772  // MemberA1 OR MemberA2 is assignable from MemberB (i.e., one member
773  // of ta that is assignable is sufficient). The spec does not clearly
774  // say which way we should do it. For now we are going with method (i).
775  const UnionCaseLabelSeq& label_seq_a = ta.union_type.member_seq[j].common.label_seq;
776  bool matched = false;
777  for (unsigned k = 0; k < label_seq_b.length(); ++k) {
778  for (unsigned t = 0; t < label_seq_a.length(); ++t) {
779  if (label_seq_b.members[k] == label_seq_a.members[t]) {
780  const TypeIdentifier& tia = ta.union_type.member_seq[j].common.type_id;
781  const TypeIdentifier& tib = tb.union_type.member_seq[i].common.type_id;
782  if (!assignable(tia, tib)) {
783  return false;
784  }
785  matched = true;
786  break;
787  }
788  }
789  if (matched) break;
790  }
791  }
792  }
793 
794  // If any non-default labels of T1 that select the default member of T2,
795  // the type of the member in T1 is assignable from the type of the default
796  // member in T2
797  for (unsigned i = 0; i < tb.union_type.member_seq.length(); ++i) {
798  const UnionMemberFlag& flags_b = tb.union_type.member_seq[i].common.member_flags;
799  if ((flags_b & IS_DEFAULT) == IS_DEFAULT) {
800  const UnionCaseLabelSeq& label_seq_b = tb.union_type.member_seq[i].common.label_seq;
801  for (unsigned j = 0; j < ta.union_type.member_seq.length(); ++j) {
802  const UnionCaseLabelSeq& label_seq_a = ta.union_type.member_seq[j].common.label_seq;
803  bool matched = false;
804  for (unsigned k = 0; k < label_seq_a.length(); ++k) {
805  for (unsigned t = 0; t < label_seq_b.length(); ++t) {
806  if (label_seq_a[k] == label_seq_b[t]) {
807  const TypeIdentifier& tia = ta.union_type.member_seq[j].common.type_id;
808  const TypeIdentifier& tib = tb.union_type.member_seq[i].common.type_id;
809  if (!assignable(tia, tib)) {
810  return false;
811  }
812  matched = true;
813  break;
814  }
815  }
816  if (matched) break;
817  }
818  }
819  break;
820  }
821  }
822 
823  // If T1 and T2 both have default labels, the type of T1's default member
824  // is assignable from the type of T2's default member
825  for (unsigned i = 0; i < ta.union_type.member_seq.length(); ++i) {
826  const UnionMemberFlag& flags_a = ta.union_type.member_seq[i].common.member_flags;
827  if ((flags_a & IS_DEFAULT) == IS_DEFAULT) {
828  for (unsigned j = 0; j < tb.union_type.member_seq.length(); ++j) {
829  const UnionMemberFlag& flags_b = tb.union_type.member_seq[j].common.member_flags;
830  if ((flags_b & IS_DEFAULT) == IS_DEFAULT) {
831  const TypeIdentifier& tia = ta.union_type.member_seq[i].common.type_id;
832  const TypeIdentifier& tib = tb.union_type.member_seq[j].common.type_id;
833  if (!assignable(tia, tib)) {
834  return false;
835  }
836  break;
837  }
838  }
839  break;
840  }
841  }
842 
843  return true;
844 }
ACE_CDR::ULong MemberId
Definition: TypeObject.h:910
MemberFlag UnionMemberFlag
Definition: TypeObject.h:380
const TypeFlag IS_MUTABLE
Definition: TypeObject.h:402
const TypeKind TK_UNION
Definition: TypeObject.h:244
TypeConsistencyAttributes type_consistency_
bool strongly_assignable(const TypeIdentifier &ta, const TypeIdentifier &tb) const
If types T1 and T2 are equivalent using the MINIMAL relation, or alternatively if T1 is-assignable-fr...
ACE_CDR::UShort MemberFlag
Definition: TypeObject.h:368
const MemberFlag IS_KEY
Definition: TypeObject.h:375
const TypeFlag IS_FINAL
Definition: TypeObject.h:400
ACE_UINT32 ULong
bool assignable(const TypeObject &ta, const TypeObject &tb) const
Both input type objects must be minimal.
typedef OPENDDS_SET(DynamicTypePtrPair) DynamicTypePtrPairSeen
const char *const name
Definition: debug.cpp:60
ACE_INT32 Long
ACE_CDR::UShort TypeFlag
Definition: TypeObject.h:399
const TypeFlag IS_APPENDABLE
Definition: TypeObject.h:401
Sequence< ACE_CDR::Long > UnionCaseLabelSeq
Definition: TypeObject.h:1534
typedef OPENDDS_MAP(TypeIdentifier, TypeObject) TypeMap
const MemberFlag IS_DEFAULT
Definition: TypeObject.h:376
ACE_CDR::Octet NameHash[4]
Definition: TypeObject.h:296

◆ assignable_union() [2/2]

bool OpenDDS::XTypes::TypeAssignability::assignable_union ( const MinimalTypeObject ta,
const TypeIdentifier tb 
) const
private

The first type must be TK_UNION. The second type can be anything.

Definition at line 850 of file TypeAssignability.cpp.

References OpenDDS::XTypes::MinimalTypeObject::alias_type, assignable_union(), OpenDDS::XTypes::MinimalAliasType::body, OpenDDS::XTypes::MinimalAliasBody::common, OpenDDS::XTypes::EK_COMPLETE, OpenDDS::XTypes::EK_MINIMAL, OpenDDS::XTypes::TypeIdentifier::kind(), OpenDDS::XTypes::MinimalTypeObject::kind, lookup_minimal(), OpenDDS::XTypes::CommonAliasBody::related_type, OpenDDS::XTypes::TK_ALIAS, and OpenDDS::XTypes::TK_UNION.

852 {
853  if (EK_MINIMAL == tb.kind()) {
854  const MinimalTypeObject& tob = lookup_minimal(tb);
855  if (TK_UNION == tob.kind) {
856  return assignable_union(ta, tob);
857  } else if (TK_ALIAS == tob.kind) {
858  const TypeIdentifier& base = tob.alias_type.body.common.related_type;
859  return assignable_union(ta, base);
860  }
861  } else if (EK_COMPLETE == tb.kind()) {
862  // Assuming tb.kind of EK_COMPLETE is not supported
863  return false;
864  }
865 
866  return false;
867 }
const TypeKind TK_UNION
Definition: TypeObject.h:244
const MinimalTypeObject & lookup_minimal(const TypeIdentifier &ti) const
const EquivalenceKind EK_COMPLETE
Definition: TypeObject.h:206
bool assignable_union(const MinimalTypeObject &ta, const MinimalTypeObject &tb) const
The first type must be TK_UNION. The second type must not be TK_ALIAS.
const TypeKind TK_ALIAS
Definition: TypeObject.h:235
const EquivalenceKind EK_MINIMAL
Definition: TypeObject.h:205

◆ equal_type_id()

bool OpenDDS::XTypes::TypeAssignability::equal_type_id ( const TypeIdentifier tia,
const TypeIdentifier tib 
) const
private

Check whether two type identifiers are equal.

Definition at line 1606 of file TypeAssignability.cpp.

References OpenDDS::XTypes::EK_COMPLETE, OpenDDS::XTypes::EK_MINIMAL, OpenDDS::XTypes::TypeIdentifier::kind(), OpenDDS::XTypes::Sequence< T >::members, OpenDDS::XTypes::TI_PLAIN_ARRAY_LARGE, OpenDDS::XTypes::TI_PLAIN_ARRAY_SMALL, OpenDDS::XTypes::TI_PLAIN_MAP_LARGE, OpenDDS::XTypes::TI_PLAIN_MAP_SMALL, OpenDDS::XTypes::TI_PLAIN_SEQUENCE_LARGE, OpenDDS::XTypes::TI_PLAIN_SEQUENCE_SMALL, OpenDDS::XTypes::TI_STRING16_LARGE, OpenDDS::XTypes::TI_STRING16_SMALL, OpenDDS::XTypes::TI_STRING8_LARGE, OpenDDS::XTypes::TI_STRING8_SMALL, OpenDDS::XTypes::TI_STRONGLY_CONNECTED_COMPONENT, OpenDDS::XTypes::TK_BOOLEAN, OpenDDS::XTypes::TK_BYTE, OpenDDS::XTypes::TK_CHAR16, OpenDDS::XTypes::TK_CHAR8, OpenDDS::XTypes::TK_FLOAT128, OpenDDS::XTypes::TK_FLOAT32, OpenDDS::XTypes::TK_FLOAT64, OpenDDS::XTypes::TK_INT16, OpenDDS::XTypes::TK_INT32, OpenDDS::XTypes::TK_INT64, OpenDDS::XTypes::TK_INT8, OpenDDS::XTypes::TK_UINT16, OpenDDS::XTypes::TK_UINT32, OpenDDS::XTypes::TK_UINT64, and OpenDDS::XTypes::TK_UINT8.

Referenced by strongly_assignable().

1608 {
1609  switch (tia.kind()) {
1610  case TK_BOOLEAN:
1611  case TK_BYTE:
1612  case TK_INT16:
1613  case TK_INT32:
1614  case TK_INT64:
1615  case TK_UINT16:
1616  case TK_UINT32:
1617  case TK_UINT64:
1618  case TK_FLOAT32:
1619  case TK_FLOAT64:
1620  case TK_FLOAT128:
1621  case TK_INT8:
1622  case TK_UINT8:
1623  case TK_CHAR8:
1624  case TK_CHAR16: {
1625  if (tib.kind() == tia.kind()) {
1626  return true;
1627  }
1628  break;
1629  }
1630  case TI_STRING8_SMALL:
1631  case TI_STRING16_SMALL: {
1632  if (tib.kind() == tia.kind() && tib.string_sdefn().bound == tia.string_sdefn().bound) {
1633  return true;
1634  }
1635  break;
1636  }
1637  case TI_STRING8_LARGE:
1638  case TI_STRING16_LARGE: {
1639  if (tib.kind() == tia.kind() && tib.string_ldefn().bound == tia.string_ldefn().bound) {
1640  return true;
1641  }
1642  break;
1643  }
1644  case TI_PLAIN_SEQUENCE_SMALL: {
1645  if (tib.kind() == tia.kind() &&
1646  tib.seq_sdefn().bound == tia.seq_sdefn().bound &&
1647  equal_type_id(*tia.seq_sdefn().element_identifier,
1648  *tib.seq_sdefn().element_identifier)) {
1649  return true;
1650  }
1651  break;
1652  }
1653  case TI_PLAIN_SEQUENCE_LARGE: {
1654  if (tib.kind() == tia.kind() &&
1655  tib.seq_ldefn().bound == tia.seq_ldefn().bound &&
1656  equal_type_id(*tia.seq_ldefn().element_identifier,
1657  *tib.seq_ldefn().element_identifier)) {
1658  return true;
1659  }
1660  break;
1661  }
1662  case TI_PLAIN_ARRAY_SMALL: {
1663  if (tib.kind() == tia.kind()) {
1664  const SBoundSeq& bounds_a = tia.array_sdefn().array_bound_seq;
1665  const SBoundSeq& bounds_b = tia.array_sdefn().array_bound_seq;
1666  if (bounds_a.members.size() != bounds_b.members.size()) {
1667  break;
1668  }
1669  bool equal_bounds = true;
1670  for (size_t i = 0; i < bounds_a.members.size(); ++i) {
1671  if (bounds_a.members[i] != bounds_b.members[i]) {
1672  equal_bounds = false;
1673  break;
1674  }
1675  }
1676  if (!equal_bounds) {
1677  break;
1678  }
1679  if (equal_type_id(*tia.array_sdefn().element_identifier,
1680  *tib.array_sdefn().element_identifier)) {
1681  return true;
1682  }
1683  }
1684  break;
1685  }
1686  case TI_PLAIN_ARRAY_LARGE: {
1687  if (tib.kind() == tia.kind()) {
1688  const LBoundSeq& bounds_a = tia.array_ldefn().array_bound_seq;
1689  const LBoundSeq& bounds_b = tib.array_ldefn().array_bound_seq;
1690  if (bounds_a.members.size() != bounds_b.members.size()) {
1691  break;
1692  }
1693  bool equal_bounds = true;
1694  for (size_t i = 0; i < bounds_a.members.size(); ++i) {
1695  if (bounds_a.members[i] != bounds_b.members[i]) {
1696  equal_bounds = false;
1697  break;
1698  }
1699  }
1700  if (!equal_bounds) {
1701  break;
1702  }
1703  if (equal_type_id(*tia.array_ldefn().element_identifier,
1704  *tib.array_ldefn().element_identifier)) {
1705  return true;
1706  }
1707  }
1708  break;
1709  }
1710  case TI_PLAIN_MAP_SMALL: {
1711  if (tib.kind() == tia.kind() &&
1712  tib.map_sdefn().bound == tia.map_sdefn().bound &&
1713  equal_type_id(*tia.map_sdefn().key_identifier,
1714  *tib.map_sdefn().key_identifier) &&
1715  equal_type_id(*tia.map_sdefn().element_identifier,
1716  *tib.map_sdefn().element_identifier)) {
1717  return true;
1718  }
1719  break;
1720  }
1721  case TI_PLAIN_MAP_LARGE: {
1722  if (tib.kind() == tia.kind() &&
1723  tib.map_ldefn().bound == tia.map_ldefn().bound &&
1724  equal_type_id(*tia.map_ldefn().key_identifier,
1725  *tib.map_ldefn().key_identifier) &&
1726  equal_type_id(*tia.map_ldefn().element_identifier,
1727  *tib.map_ldefn().element_identifier)) {
1728  return true;
1729  }
1730  break;
1731  }
1733  if (tib.kind() == tia.kind() &&
1734  tib.sc_component_id().scc_length == tia.sc_component_id().scc_length &&
1735  tib.sc_component_id().sc_component_id.kind ==
1736  tia.sc_component_id().sc_component_id.kind) {
1737  const EquivalenceHash& ha = tia.sc_component_id().sc_component_id.hash;
1738  const EquivalenceHash& hb = tib.sc_component_id().sc_component_id.hash;
1739  bool equal_hash = true;
1740  for (size_t i = 0; i < 14; ++i) {
1741  if (ha[i] != hb[i]) {
1742  equal_hash = false;
1743  break;
1744  }
1745  }
1746  if (equal_hash) {
1747  return true;
1748  }
1749  }
1750  break;
1751  }
1752  case EK_COMPLETE:
1753  case EK_MINIMAL: {
1754  if (tib.kind() == tia.kind()) {
1755  bool equal_hash = true;
1756  for (size_t i = 0; i < 14; ++i) {
1757  if (tia.equivalence_hash()[i] != tib.equivalence_hash()[i]) {
1758  equal_hash = false;
1759  break;
1760  }
1761  }
1762  if (equal_hash) {
1763  return true;
1764  }
1765  }
1766  break;
1767  }
1768  default:
1769  return false; // Future extensions
1770  }
1771 
1772  return false;
1773 }
const TypeKind TK_INT32
Definition: TypeObject.h:217
const TypeKind TK_FLOAT128
Definition: TypeObject.h:224
const TypeIdentifierKind TI_STRING8_LARGE
Definition: TypeObject.h:256
const TypeKind TK_BYTE
Definition: TypeObject.h:215
const TypeKind TK_INT16
Definition: TypeObject.h:216
bool equal_type_id(const TypeIdentifier &tia, const TypeIdentifier &tib) const
Check whether two type identifiers are equal.
const TypeIdentifierKind TI_PLAIN_SEQUENCE_LARGE
Definition: TypeObject.h:261
const TypeKind TK_UINT16
Definition: TypeObject.h:219
const TypeIdentifierKind TI_STRING16_LARGE
Definition: TypeObject.h:258
const TypeKind TK_INT8
Definition: TypeObject.h:225
const TypeIdentifierKind TI_STRING8_SMALL
Definition: TypeObject.h:255
const EquivalenceKind EK_COMPLETE
Definition: TypeObject.h:206
const TypeIdentifierKind TI_PLAIN_MAP_LARGE
Definition: TypeObject.h:267
const TypeKind TK_BOOLEAN
Definition: TypeObject.h:214
const TypeIdentifierKind TI_PLAIN_MAP_SMALL
Definition: TypeObject.h:266
const TypeIdentifierKind TI_PLAIN_ARRAY_LARGE
Definition: TypeObject.h:264
const TypeIdentifierKind TI_PLAIN_ARRAY_SMALL
Definition: TypeObject.h:263
Sequence< SBound > SBoundSeq
Definition: TypeObject.h:318
const TypeKind TK_CHAR8
Definition: TypeObject.h:227
const TypeKind TK_FLOAT32
Definition: TypeObject.h:222
ACE_CDR::Octet EquivalenceHash[14]
Definition: TypeObject.h:287
const TypeKind TK_UINT64
Definition: TypeObject.h:221
const TypeKind TK_INT64
Definition: TypeObject.h:218
const TypeKind TK_UINT32
Definition: TypeObject.h:220
const TypeIdentifierKind TI_PLAIN_SEQUENCE_SMALL
Definition: TypeObject.h:260
Sequence< LBound > LBoundSeq
Definition: TypeObject.h:313
const EquivalenceKind EK_MINIMAL
Definition: TypeObject.h:205
const TypeIdentifierKind TI_STRING16_SMALL
Definition: TypeObject.h:257
const TypeIdentifierKind TI_STRONGLY_CONNECTED_COMPONENT
Definition: TypeObject.h:269
const TypeKind TK_UINT8
Definition: TypeObject.h:226
const TypeKind TK_CHAR16
Definition: TypeObject.h:228
const TypeKind TK_FLOAT64
Definition: TypeObject.h:223

◆ erase_key()

void OpenDDS::XTypes::TypeAssignability::erase_key ( MinimalTypeObject type) const
private

Key-Erased type of an aggregated type T (struct or union) is constructed from T by removing the key designation from any member that has it (sub-clause 7.2.2.4.6). The input type must be either a struct or an union.

Definition at line 1881 of file TypeAssignability.cpp.

References OpenDDS::XTypes::MinimalDiscriminatorMember::common, OpenDDS::XTypes::MinimalUnionType::discriminator, OpenDDS::XTypes::IS_KEY, OpenDDS::XTypes::MinimalTypeObject::kind, OpenDDS::XTypes::CommonDiscriminatorMember::member_flags, OpenDDS::XTypes::MinimalStructType::member_seq, OpenDDS::XTypes::Sequence< T >::members, OpenDDS::XTypes::MinimalTypeObject::struct_type, OpenDDS::XTypes::TK_STRUCTURE, OpenDDS::XTypes::TK_UNION, and OpenDDS::XTypes::MinimalTypeObject::union_type.

Referenced by assignable_struct().

1882 {
1883  if (TK_STRUCTURE == type.kind) {
1884  MinimalStructMemberSeq& mseq = type.struct_type.member_seq;
1885  for (size_t i = 0; i < mseq.members.size(); ++i) {
1886  MemberFlag& flags = mseq.members[i].common.member_flags;
1887  if ((flags & IS_KEY) == IS_KEY) {
1888  flags &= ~IS_KEY;
1889  }
1890  }
1891  } else if (TK_UNION == type.kind) {
1892  MemberFlag& flags = type.union_type.discriminator.common.member_flags;
1893  if ((flags & IS_KEY) == IS_KEY) {
1894  flags &= ~IS_KEY;
1895  }
1896  }
1897 }
const TypeKind TK_UNION
Definition: TypeObject.h:244
Sequence< MinimalStructMember > MinimalStructMemberSeq
Definition: TypeObject.h:1367
ACE_CDR::UShort MemberFlag
Definition: TypeObject.h:368
const MemberFlag IS_KEY
Definition: TypeObject.h:375
const TypeKind TK_STRUCTURE
Definition: TypeObject.h:243

◆ get_base_type()

const TypeIdentifier & OpenDDS::XTypes::TypeAssignability::get_base_type ( const MinimalTypeObject type) const
private

The input must be of type TK_ALIAS Return the non-alias base type identifier of the input.

Definition at line 1975 of file TypeAssignability.cpp.

References OpenDDS::XTypes::MinimalTypeObject::alias_type, OpenDDS::XTypes::MinimalAliasType::body, OpenDDS::XTypes::MinimalAliasBody::common, OpenDDS::XTypes::EK_COMPLETE, OpenDDS::XTypes::EK_MINIMAL, OpenDDS::XTypes::TypeIdentifier::kind(), OpenDDS::XTypes::MinimalTypeObject::kind, lookup_minimal(), OpenDDS::XTypes::CommonAliasBody::related_type, and OpenDDS::XTypes::TK_ALIAS.

Referenced by assignable(), assignable_struct(), get_map_bound(), get_sequence_bound(), get_string_bound(), get_struct_member(), get_union_member(), hold_key(), is_delimited(), and struct_rule_enum_key().

1976 {
1977  const TypeIdentifier& base = type.alias_type.body.common.related_type;
1978  switch (base.kind()) {
1979  case EK_COMPLETE:
1980  case EK_MINIMAL: {
1981  const MinimalTypeObject& type_obj = lookup_minimal(base);
1982  if (TK_ALIAS == type_obj.kind) {
1983  return get_base_type(type_obj);
1984  }
1985  return base;
1986  }
1987  default:
1988  return base;
1989  }
1990 }
const MinimalTypeObject & lookup_minimal(const TypeIdentifier &ti) const
const TypeIdentifier & get_base_type(const MinimalTypeObject &type) const
The input must be of type TK_ALIAS Return the non-alias base type identifier of the input...
const EquivalenceKind EK_COMPLETE
Definition: TypeObject.h:206
const TypeKind TK_ALIAS
Definition: TypeObject.h:235
const EquivalenceKind EK_MINIMAL
Definition: TypeObject.h:205

◆ get_map_bound()

bool OpenDDS::XTypes::TypeAssignability::get_map_bound ( LBound b,
const CommonStructMember m 
) const
private

Check whether a struct member is of map type and if so compute its bound into the first argument.

Definition at line 2089 of file TypeAssignability.cpp.

References OpenDDS::XTypes::CommonCollectionHeader::bound, OpenDDS::XTypes::MinimalCollectionHeader::common, OpenDDS::XTypes::EK_MINIMAL, get_base_type(), OpenDDS::XTypes::MinimalMapType::header, OpenDDS::XTypes::TypeIdentifier::kind(), OpenDDS::XTypes::MinimalTypeObject::kind, lookup_minimal(), OpenDDS::XTypes::MinimalTypeObject::map_type, OpenDDS::XTypes::CommonStructMember::member_type_id, OpenDDS::XTypes::TI_PLAIN_MAP_LARGE, OpenDDS::XTypes::TI_PLAIN_MAP_SMALL, OpenDDS::XTypes::TK_ALIAS, and OpenDDS::XTypes::TK_MAP.

Referenced by assignable_struct().

2091 {
2092  ACE_CDR::Octet kind = member.member_type_id.kind();
2093  bool is_map = false;
2094  if (EK_MINIMAL == kind) {
2095  const MinimalTypeObject& tobj = lookup_minimal(member.member_type_id);
2096  if (TK_MAP == tobj.kind) {
2097  bound = tobj.map_type.header.common.bound;
2098  is_map = true;
2099  } else if (TK_ALIAS == tobj.kind) {
2100  const TypeIdentifier& base = get_base_type(tobj);
2101  if (EK_MINIMAL == base.kind()) {
2102  const MinimalTypeObject& base_obj = lookup_minimal(base);
2103  if (TK_MAP == base_obj.kind) {
2104  bound = base_obj.map_type.header.common.bound;
2105  is_map = true;
2106  }
2107  } else if (TI_PLAIN_MAP_SMALL == base.kind()) {
2108  bound = static_cast<LBound>(base.map_sdefn().bound);
2109  is_map = true;
2110  } else if (TI_PLAIN_MAP_LARGE == base.kind()) {
2111  bound = base.map_ldefn().bound;
2112  is_map = true;
2113  }
2114  }
2115  } else if (TI_PLAIN_MAP_SMALL == kind) {
2116  bound = static_cast<LBound>(member.member_type_id.map_sdefn().bound);
2117  is_map = true;
2118  } else if (TI_PLAIN_MAP_LARGE == kind) {
2119  bound = member.member_type_id.map_ldefn().bound;
2120  is_map = true;
2121  }
2122  return is_map;
2123 }
ACE_Byte Octet
const MinimalTypeObject & lookup_minimal(const TypeIdentifier &ti) const
const TypeIdentifier & get_base_type(const MinimalTypeObject &type) const
The input must be of type TK_ALIAS Return the non-alias base type identifier of the input...
const TypeIdentifierKind TI_PLAIN_MAP_LARGE
Definition: TypeObject.h:267
const TypeIdentifierKind TI_PLAIN_MAP_SMALL
Definition: TypeObject.h:266
const TypeKind TK_ALIAS
Definition: TypeObject.h:235
const EquivalenceKind EK_MINIMAL
Definition: TypeObject.h:205
ACE_CDR::ULong LBound
Definition: TypeObject.h:312
const TypeKind TK_MAP
Definition: TypeObject.h:250

◆ get_sequence_bound()

bool OpenDDS::XTypes::TypeAssignability::get_sequence_bound ( LBound b,
const CommonStructMember m 
) const
private

Check whether a struct member is of sequence type and if so compute its bound into the first argument.

Definition at line 2049 of file TypeAssignability.cpp.

References OpenDDS::XTypes::CommonCollectionHeader::bound, OpenDDS::XTypes::MinimalCollectionHeader::common, OpenDDS::XTypes::EK_MINIMAL, get_base_type(), OpenDDS::XTypes::MinimalSequenceType::header, OpenDDS::XTypes::TypeIdentifier::kind(), OpenDDS::XTypes::MinimalTypeObject::kind, lookup_minimal(), OpenDDS::XTypes::CommonStructMember::member_type_id, OpenDDS::XTypes::MinimalTypeObject::sequence_type, OpenDDS::XTypes::TI_PLAIN_SEQUENCE_LARGE, OpenDDS::XTypes::TI_PLAIN_SEQUENCE_SMALL, OpenDDS::XTypes::TK_ALIAS, and OpenDDS::XTypes::TK_SEQUENCE.

Referenced by assignable_struct().

2051 {
2052  ACE_CDR::Octet kind = member.member_type_id.kind();
2053  bool is_sequence = false;
2054  if (EK_MINIMAL == kind) {
2055  const MinimalTypeObject& tobj = lookup_minimal(member.member_type_id);
2056  if (TK_SEQUENCE == tobj.kind) {
2057  bound = tobj.sequence_type.header.common.bound;
2058  is_sequence = true;
2059  } else if (TK_ALIAS == tobj.kind) {
2060  const TypeIdentifier& base = get_base_type(tobj);
2061  if (EK_MINIMAL == base.kind()) {
2062  const MinimalTypeObject& base_obj = lookup_minimal(base);
2063  if (TK_SEQUENCE == base_obj.kind) {
2064  bound = base_obj.sequence_type.header.common.bound;
2065  is_sequence = true;
2066  }
2067  } else if (TI_PLAIN_SEQUENCE_SMALL == base.kind()) {
2068  bound = static_cast<LBound>(base.seq_sdefn().bound);
2069  is_sequence = true;
2070  } else if (TI_PLAIN_SEQUENCE_LARGE == base.kind()) {
2071  bound = base.seq_ldefn().bound;
2072  is_sequence = true;
2073  }
2074  }
2075  } else if (TI_PLAIN_SEQUENCE_SMALL == kind) {
2076  bound = static_cast<LBound>(member.member_type_id.seq_sdefn().bound);
2077  is_sequence = true;
2078  } else if (TI_PLAIN_SEQUENCE_LARGE == kind) {
2079  bound = member.member_type_id.seq_ldefn().bound;
2080  is_sequence = true;
2081  }
2082  return is_sequence;
2083 }
ACE_Byte Octet
const TypeKind TK_SEQUENCE
Definition: TypeObject.h:248
const TypeIdentifierKind TI_PLAIN_SEQUENCE_LARGE
Definition: TypeObject.h:261
const MinimalTypeObject & lookup_minimal(const TypeIdentifier &ti) const
const TypeIdentifier & get_base_type(const MinimalTypeObject &type) const
The input must be of type TK_ALIAS Return the non-alias base type identifier of the input...
const TypeKind TK_ALIAS
Definition: TypeObject.h:235
const TypeIdentifierKind TI_PLAIN_SEQUENCE_SMALL
Definition: TypeObject.h:260
const EquivalenceKind EK_MINIMAL
Definition: TypeObject.h:205
ACE_CDR::ULong LBound
Definition: TypeObject.h:312

◆ get_string_bound()

bool OpenDDS::XTypes::TypeAssignability::get_string_bound ( LBound b,
const CommonStructMember m 
) const
private

Check whether the input struct member is of string type and if so compute its bound into the first argument.

Definition at line 2129 of file TypeAssignability.cpp.

References OpenDDS::XTypes::EK_MINIMAL, get_base_type(), OpenDDS::XTypes::TypeIdentifier::kind(), OpenDDS::XTypes::MinimalTypeObject::kind, lookup_minimal(), OpenDDS::XTypes::CommonStructMember::member_type_id, OpenDDS::XTypes::TI_STRING16_LARGE, OpenDDS::XTypes::TI_STRING16_SMALL, OpenDDS::XTypes::TI_STRING8_LARGE, OpenDDS::XTypes::TI_STRING8_SMALL, and OpenDDS::XTypes::TK_ALIAS.

Referenced by assignable_struct().

2131 {
2132  ACE_CDR::Octet kind = member.member_type_id.kind();
2133  bool is_string = false;
2134  if (EK_MINIMAL == kind) {
2135  const MinimalTypeObject& tobj = lookup_minimal(member.member_type_id);
2136  if (TK_ALIAS == tobj.kind) {
2137  const TypeIdentifier& base = get_base_type(tobj);
2138  if (TI_STRING8_SMALL == base.kind() || TI_STRING16_SMALL == base.kind()) {
2139  bound = static_cast<LBound>(base.string_sdefn().bound);
2140  is_string = true;
2141  } else if (TI_STRING8_LARGE == base.kind() || TI_STRING16_LARGE == base.kind()) {
2142  bound = base.string_ldefn().bound;
2143  is_string = true;
2144  }
2145  }
2146  } else if (TI_STRING8_SMALL == kind || TI_STRING16_SMALL == kind) {
2147  bound = static_cast<LBound>(member.member_type_id.string_sdefn().bound);
2148  is_string = true;
2149  } else if (TI_STRING8_LARGE == kind || TI_STRING16_LARGE == kind) {
2150  bound = member.member_type_id.string_ldefn().bound;
2151  is_string = true;
2152  }
2153  return is_string;
2154 }
ACE_Byte Octet
const TypeIdentifierKind TI_STRING8_LARGE
Definition: TypeObject.h:256
const MinimalTypeObject & lookup_minimal(const TypeIdentifier &ti) const
const TypeIdentifierKind TI_STRING16_LARGE
Definition: TypeObject.h:258
const TypeIdentifier & get_base_type(const MinimalTypeObject &type) const
The input must be of type TK_ALIAS Return the non-alias base type identifier of the input...
const TypeIdentifierKind TI_STRING8_SMALL
Definition: TypeObject.h:255
const TypeKind TK_ALIAS
Definition: TypeObject.h:235
const EquivalenceKind EK_MINIMAL
Definition: TypeObject.h:205
const TypeIdentifierKind TI_STRING16_SMALL
Definition: TypeObject.h:257
ACE_CDR::ULong LBound
Definition: TypeObject.h:312

◆ get_struct_member()

bool OpenDDS::XTypes::TypeAssignability::get_struct_member ( const MinimalTypeObject *&  ret,
const CommonStructMember m 
) const
private

Check if the second argument is of a struct type and if so return its type object as the first argument.

Definition at line 2160 of file TypeAssignability.cpp.

References OpenDDS::XTypes::EK_MINIMAL, get_base_type(), OpenDDS::XTypes::TypeIdentifier::kind(), OpenDDS::XTypes::MinimalTypeObject::kind, lookup_minimal(), OpenDDS::XTypes::CommonStructMember::member_type_id, OpenDDS::XTypes::TK_ALIAS, and OpenDDS::XTypes::TK_STRUCTURE.

Referenced by assignable_struct().

2162 {
2163  ACE_CDR::Octet kind = member.member_type_id.kind();
2164  bool is_struct = false;
2165  if (EK_MINIMAL == kind) {
2166  const MinimalTypeObject& tobj = lookup_minimal(member.member_type_id);
2167  if (TK_STRUCTURE == tobj.kind) {
2168  ret = &tobj;
2169  is_struct = true;
2170  } else if (TK_ALIAS == tobj.kind) {
2171  const TypeIdentifier& base = get_base_type(tobj);
2172  if (EK_MINIMAL == base.kind()) {
2173  const MinimalTypeObject& base_obj = lookup_minimal(base);
2174  if (TK_STRUCTURE == base_obj.kind) {
2175  ret = &base_obj;
2176  is_struct = true;
2177  }
2178  }
2179  }
2180  }
2181  return is_struct;
2182 }
ACE_Byte Octet
const MinimalTypeObject & lookup_minimal(const TypeIdentifier &ti) const
const TypeIdentifier & get_base_type(const MinimalTypeObject &type) const
The input must be of type TK_ALIAS Return the non-alias base type identifier of the input...
const TypeKind TK_STRUCTURE
Definition: TypeObject.h:243
const TypeKind TK_ALIAS
Definition: TypeObject.h:235
const EquivalenceKind EK_MINIMAL
Definition: TypeObject.h:205

◆ get_union_member()

bool OpenDDS::XTypes::TypeAssignability::get_union_member ( const MinimalTypeObject *&  ret,
const CommonStructMember m 
) const
private

Check if the second argument is of a union type and if so return its type object as the first argument.

Definition at line 2188 of file TypeAssignability.cpp.

References OpenDDS::XTypes::EK_MINIMAL, get_base_type(), OpenDDS::XTypes::TypeIdentifier::kind(), OpenDDS::XTypes::MinimalTypeObject::kind, lookup_minimal(), OpenDDS::XTypes::CommonStructMember::member_type_id, OPENDDS_END_VERSIONED_NAMESPACE_DECL, OpenDDS::XTypes::TK_ALIAS, and OpenDDS::XTypes::TK_UNION.

Referenced by assignable_struct().

2190 {
2191  ACE_CDR::Octet kind = member.member_type_id.kind();
2192  bool is_union = false;
2193  if (EK_MINIMAL == kind) {
2194  const MinimalTypeObject& tobj = lookup_minimal(member.member_type_id);
2195  if (TK_UNION == tobj.kind) {
2196  ret = &tobj;
2197  is_union = true;
2198  } else if (TK_ALIAS == tobj.kind) {
2199  const TypeIdentifier& base = get_base_type(tobj);
2200  if (EK_MINIMAL == base.kind()) {
2201  const MinimalTypeObject& base_obj = lookup_minimal(base);
2202  if (TK_UNION == base_obj.kind) {
2203  ret = &base_obj;
2204  is_union = true;
2205  }
2206  }
2207  }
2208  }
2209  return is_union;
2210 }
ACE_Byte Octet
const TypeKind TK_UNION
Definition: TypeObject.h:244
const MinimalTypeObject & lookup_minimal(const TypeIdentifier &ti) const
const TypeIdentifier & get_base_type(const MinimalTypeObject &type) const
The input must be of type TK_ALIAS Return the non-alias base type identifier of the input...
const TypeKind TK_ALIAS
Definition: TypeObject.h:235
const EquivalenceKind EK_MINIMAL
Definition: TypeObject.h:205

◆ hold_key() [1/2]

void OpenDDS::XTypes::TypeAssignability::hold_key ( MinimalTypeObject type) const
private

Key-Holder type of an aggregated type T (struct or union) is constructed from T (sub-clause 7.2.2.4.7) The input MinimalTypeObject is modified to get the corresponding KeyHolder type. The input must be either a struct or an union.

Definition at line 1905 of file TypeAssignability.cpp.

References OpenDDS::XTypes::Sequence< T >::append(), OpenDDS::XTypes::MinimalDiscriminatorMember::common, OpenDDS::XTypes::MinimalUnionType::discriminator, OpenDDS::XTypes::IS_KEY, OpenDDS::XTypes::MinimalTypeObject::kind, OpenDDS::XTypes::CommonDiscriminatorMember::member_flags, OpenDDS::XTypes::MinimalStructType::member_seq, OpenDDS::XTypes::MinimalUnionType::member_seq, OpenDDS::XTypes::Sequence< T >::members, OpenDDS::XTypes::MinimalTypeObject::struct_type, OpenDDS::XTypes::TK_STRUCTURE, OpenDDS::XTypes::TK_UNION, and OpenDDS::XTypes::MinimalTypeObject::union_type.

Referenced by assignable_struct(), and hold_key().

1906 {
1907  if (TK_STRUCTURE == type.kind) {
1908  MinimalStructMemberSeq& mseq = type.struct_type.member_seq;
1909  bool found_key = false;
1910  for (size_t i = 0; i < mseq.members.size(); ++i) {
1911  const MemberFlag& flags = mseq.members[i].common.member_flags;
1912  if ((flags & IS_KEY) == IS_KEY) {
1913  found_key = true;
1914  break;
1915  }
1916  }
1917 
1918  if (found_key) { // Remove all non-key members
1919  Sequence<MinimalStructMember> key_members;
1920  for (size_t i = 0; i < mseq.members.size(); ++i) {
1921  const MemberFlag& flags = mseq.members[i].common.member_flags;
1922  if ((flags & IS_KEY) == IS_KEY) {
1923  key_members.append(mseq.members[i]);
1924  }
1925  }
1926  mseq.members = key_members.members;
1927  } else { // Add a key designator to each member
1928  for (size_t i = 0; i < mseq.members.size(); ++i) {
1929  const MemberFlag& flags = mseq.members[i].common.member_flags;
1930  if ((flags & IS_KEY) != IS_KEY) {
1931  mseq.members[i].common.member_flags |= IS_KEY;
1932  }
1933  }
1934  }
1935  } else if (TK_UNION == type.kind) {
1936  if ((type.union_type.discriminator.common.member_flags & IS_KEY) == IS_KEY) {
1937  // Remove all non-key members
1938  type.union_type.member_seq = Sequence<MinimalUnionMember>();
1939  }
1940  }
1941 }
const TypeKind TK_UNION
Definition: TypeObject.h:244
Sequence< MinimalStructMember > MinimalStructMemberSeq
Definition: TypeObject.h:1367
ACE_CDR::UShort MemberFlag
Definition: TypeObject.h:368
const MemberFlag IS_KEY
Definition: TypeObject.h:375
const TypeKind TK_STRUCTURE
Definition: TypeObject.h:243

◆ hold_key() [2/2]

bool OpenDDS::XTypes::TypeAssignability::hold_key ( const TypeIdentifier ti,
MinimalTypeObject to 
) const
private

Return false if the input type does not have type object; the output MinimalTypeObject is not used in this case. Return true if the input type has type object; the output MinimalTypeObject contains the KeyHolder type of the corresponding type.

Definition at line 1949 of file TypeAssignability.cpp.

References OpenDDS::XTypes::EK_COMPLETE, OpenDDS::XTypes::EK_MINIMAL, get_base_type(), hold_key(), OpenDDS::XTypes::TypeIdentifier::kind(), OpenDDS::XTypes::MinimalTypeObject::kind, lookup_minimal(), OpenDDS::XTypes::TK_ALIAS, OpenDDS::XTypes::TK_STRUCTURE, and OpenDDS::XTypes::TK_UNION.

1950 {
1951  if (EK_MINIMAL != ti.kind() && EK_COMPLETE != ti.kind()) {
1952  return false;
1953  }
1954 
1955  to = lookup_minimal(ti);
1956  switch (to.kind) {
1957  case TK_STRUCTURE:
1958  case TK_UNION: {
1959  hold_key(to);
1960  return true;
1961  }
1962  case TK_ALIAS: {
1963  const TypeIdentifier& base = get_base_type(to);
1964  return hold_key(base, to);
1965  }
1966  default: // KeyHolder is not defined for other types
1967  return true;
1968  }
1969 }
const TypeKind TK_UNION
Definition: TypeObject.h:244
const MinimalTypeObject & lookup_minimal(const TypeIdentifier &ti) const
const TypeIdentifier & get_base_type(const MinimalTypeObject &type) const
The input must be of type TK_ALIAS Return the non-alias base type identifier of the input...
const EquivalenceKind EK_COMPLETE
Definition: TypeObject.h:206
const TypeKind TK_STRUCTURE
Definition: TypeObject.h:243
void hold_key(MinimalTypeObject &type) const
Key-Holder type of an aggregated type T (struct or union) is constructed from T (sub-clause 7...
const TypeKind TK_ALIAS
Definition: TypeObject.h:235
const EquivalenceKind EK_MINIMAL
Definition: TypeObject.h:205

◆ insert_entry()

void OpenDDS::XTypes::TypeAssignability::insert_entry ( const TypeIdentifier ti,
const TypeObject tobj 
)
inline

Definition at line 85 of file TypeAssignability.h.

References OpenDDS::XTypes::get_base_type().

86  {
87  tl_service_->add(ti, tobj);
88  }
XTypes::TypeLookupService_rch tl_service_

◆ is_delimited() [1/2]

bool OpenDDS::XTypes::TypeAssignability::is_delimited ( const TypeIdentifier ti) const
private

Concept of delimited types (sub-clause 7.2.4.2)

Definition at line 1778 of file TypeAssignability.cpp.

References OpenDDS::XTypes::EK_COMPLETE, OpenDDS::XTypes::EK_MINIMAL, OpenDDS::XTypes::TypeIdentifier::kind(), lookup_minimal(), OpenDDS::XTypes::TI_PLAIN_ARRAY_LARGE, OpenDDS::XTypes::TI_PLAIN_ARRAY_SMALL, OpenDDS::XTypes::TI_PLAIN_MAP_LARGE, OpenDDS::XTypes::TI_PLAIN_MAP_SMALL, OpenDDS::XTypes::TI_PLAIN_SEQUENCE_LARGE, OpenDDS::XTypes::TI_PLAIN_SEQUENCE_SMALL, OpenDDS::XTypes::TI_STRING16_LARGE, OpenDDS::XTypes::TI_STRING16_SMALL, OpenDDS::XTypes::TI_STRING8_LARGE, OpenDDS::XTypes::TI_STRING8_SMALL, OpenDDS::XTypes::TK_BOOLEAN, OpenDDS::XTypes::TK_BYTE, OpenDDS::XTypes::TK_CHAR16, OpenDDS::XTypes::TK_CHAR8, OpenDDS::XTypes::TK_FLOAT128, OpenDDS::XTypes::TK_FLOAT32, OpenDDS::XTypes::TK_FLOAT64, OpenDDS::XTypes::TK_INT16, OpenDDS::XTypes::TK_INT32, OpenDDS::XTypes::TK_INT64, OpenDDS::XTypes::TK_INT8, OpenDDS::XTypes::TK_UINT16, OpenDDS::XTypes::TK_UINT32, OpenDDS::XTypes::TK_UINT64, and OpenDDS::XTypes::TK_UINT8.

Referenced by is_delimited(), and strongly_assignable().

1779 {
1780  switch (ti.kind()) {
1781  case TK_BOOLEAN:
1782  case TK_BYTE:
1783  case TK_INT16:
1784  case TK_INT32:
1785  case TK_INT64:
1786  case TK_UINT16:
1787  case TK_UINT32:
1788  case TK_UINT64:
1789  case TK_FLOAT32:
1790  case TK_FLOAT64:
1791  case TK_FLOAT128:
1792  case TK_INT8:
1793  case TK_UINT8:
1794  case TK_CHAR8:
1795  case TK_CHAR16:
1796  case TI_STRING8_SMALL:
1797  case TI_STRING8_LARGE:
1798  case TI_STRING16_SMALL:
1799  case TI_STRING16_LARGE:
1800  return true;
1802  return is_delimited(*ti.seq_sdefn().element_identifier);
1804  return is_delimited(*ti.seq_ldefn().element_identifier);
1805  case TI_PLAIN_ARRAY_SMALL:
1806  return is_delimited(*ti.array_sdefn().element_identifier);
1807  case TI_PLAIN_ARRAY_LARGE:
1808  return is_delimited(*ti.array_ldefn().element_identifier);
1809  case TI_PLAIN_MAP_SMALL:
1810  return is_delimited(*ti.map_sdefn().key_identifier) &&
1811  is_delimited(*ti.map_sdefn().element_identifier);
1812  case TI_PLAIN_MAP_LARGE:
1813  return is_delimited(*ti.map_ldefn().key_identifier) &&
1814  is_delimited(*ti.map_ldefn().element_identifier);
1815  case EK_COMPLETE:
1816  case EK_MINIMAL: {
1817  const MinimalTypeObject& tobj = lookup_minimal(ti);
1818  return is_delimited(tobj);
1819  }
1820  default:
1821  // Future extensions and strongly connected components
1822  return false;
1823  }
1824 }
const TypeKind TK_INT32
Definition: TypeObject.h:217
const TypeKind TK_FLOAT128
Definition: TypeObject.h:224
const TypeIdentifierKind TI_STRING8_LARGE
Definition: TypeObject.h:256
const TypeKind TK_BYTE
Definition: TypeObject.h:215
bool is_delimited(const TypeIdentifier &ti) const
Concept of delimited types (sub-clause 7.2.4.2)
const TypeKind TK_INT16
Definition: TypeObject.h:216
const TypeIdentifierKind TI_PLAIN_SEQUENCE_LARGE
Definition: TypeObject.h:261
const MinimalTypeObject & lookup_minimal(const TypeIdentifier &ti) const
const TypeKind TK_UINT16
Definition: TypeObject.h:219
const TypeIdentifierKind TI_STRING16_LARGE
Definition: TypeObject.h:258
const TypeKind TK_INT8
Definition: TypeObject.h:225
const TypeIdentifierKind TI_STRING8_SMALL
Definition: TypeObject.h:255
const EquivalenceKind EK_COMPLETE
Definition: TypeObject.h:206
const TypeIdentifierKind TI_PLAIN_MAP_LARGE
Definition: TypeObject.h:267
const TypeKind TK_BOOLEAN
Definition: TypeObject.h:214
const TypeIdentifierKind TI_PLAIN_MAP_SMALL
Definition: TypeObject.h:266
const TypeIdentifierKind TI_PLAIN_ARRAY_LARGE
Definition: TypeObject.h:264
const TypeIdentifierKind TI_PLAIN_ARRAY_SMALL
Definition: TypeObject.h:263
const TypeKind TK_CHAR8
Definition: TypeObject.h:227
const TypeKind TK_FLOAT32
Definition: TypeObject.h:222
const TypeKind TK_UINT64
Definition: TypeObject.h:221
const TypeKind TK_INT64
Definition: TypeObject.h:218
const TypeKind TK_UINT32
Definition: TypeObject.h:220
const TypeIdentifierKind TI_PLAIN_SEQUENCE_SMALL
Definition: TypeObject.h:260
const EquivalenceKind EK_MINIMAL
Definition: TypeObject.h:205
const TypeIdentifierKind TI_STRING16_SMALL
Definition: TypeObject.h:257
const TypeKind TK_UINT8
Definition: TypeObject.h:226
const TypeKind TK_CHAR16
Definition: TypeObject.h:228
const TypeKind TK_FLOAT64
Definition: TypeObject.h:223

◆ is_delimited() [2/2]

bool OpenDDS::XTypes::TypeAssignability::is_delimited ( const MinimalTypeObject tobj) const
private

Check if a type is delimited (sub-clause 7.2.4.2)

Definition at line 1829 of file TypeAssignability.cpp.

References OpenDDS::XTypes::MinimalAnnotationType::annotation_flag, OpenDDS::XTypes::MinimalTypeObject::annotation_type, OpenDDS::XTypes::MinimalTypeObject::array_type, OpenDDS::XTypes::MinimalBitsetType::bitset_flags, OpenDDS::XTypes::MinimalTypeObject::bitset_type, OpenDDS::XTypes::MinimalCollectionElement::common, OpenDDS::XTypes::MinimalSequenceType::element, OpenDDS::XTypes::MinimalArrayType::element, OpenDDS::XTypes::MinimalMapType::element, get_base_type(), is_delimited(), is_delimited_with_flags(), OpenDDS::XTypes::MinimalMapType::key, OpenDDS::XTypes::MinimalTypeObject::kind, OpenDDS::XTypes::MinimalTypeObject::map_type, OpenDDS::XTypes::MinimalTypeObject::sequence_type, OpenDDS::XTypes::MinimalStructType::struct_flags, OpenDDS::XTypes::MinimalTypeObject::struct_type, OpenDDS::XTypes::TK_ALIAS, OpenDDS::XTypes::TK_ANNOTATION, OpenDDS::XTypes::TK_ARRAY, OpenDDS::XTypes::TK_BITMASK, OpenDDS::XTypes::TK_BITSET, OpenDDS::XTypes::TK_ENUM, OpenDDS::XTypes::TK_MAP, OpenDDS::XTypes::TK_SEQUENCE, OpenDDS::XTypes::TK_STRUCTURE, OpenDDS::XTypes::TK_UNION, OpenDDS::XTypes::CommonCollectionElement::type, OpenDDS::XTypes::MinimalUnionType::union_flags, and OpenDDS::XTypes::MinimalTypeObject::union_type.

1830 {
1831  switch (tobj.kind) {
1832  case TK_ALIAS: {
1833  const TypeIdentifier& base = get_base_type(tobj);
1834  return is_delimited(base);
1835  }
1836  case TK_ANNOTATION:
1837  return is_delimited_with_flags(tobj.annotation_type.annotation_flag);
1838  case TK_STRUCTURE:
1839  return is_delimited_with_flags(tobj.struct_type.struct_flags);
1840  case TK_UNION:
1841  return is_delimited_with_flags(tobj.union_type.union_flags);
1842  case TK_BITSET:
1843  return is_delimited_with_flags(tobj.bitset_type.bitset_flags);
1844  case TK_SEQUENCE:
1845  return is_delimited(tobj.sequence_type.element.common.type);
1846  case TK_ARRAY:
1847  return is_delimited(tobj.array_type.element.common.type);
1848  case TK_MAP:
1849  return is_delimited(tobj.map_type.key.common.type) &&
1850  is_delimited(tobj.map_type.element.common.type);
1851  case TK_ENUM:
1852  case TK_BITMASK:
1853  return true;
1854  default:
1855  return false; // Future extensions
1856  }
1857 }
const TypeKind TK_SEQUENCE
Definition: TypeObject.h:248
bool is_delimited_with_flags(TypeFlag flags) const
const TypeKind TK_UNION
Definition: TypeObject.h:244
bool is_delimited(const TypeIdentifier &ti) const
Concept of delimited types (sub-clause 7.2.4.2)
const TypeIdentifier & get_base_type(const MinimalTypeObject &type) const
The input must be of type TK_ALIAS Return the non-alias base type identifier of the input...
const TypeKind TK_BITMASK
Definition: TypeObject.h:239
const TypeKind TK_STRUCTURE
Definition: TypeObject.h:243
const TypeKind TK_ALIAS
Definition: TypeObject.h:235
const TypeKind TK_ANNOTATION
Definition: TypeObject.h:242
const TypeKind TK_ENUM
Definition: TypeObject.h:238
const TypeKind TK_ARRAY
Definition: TypeObject.h:249
const TypeKind TK_MAP
Definition: TypeObject.h:250
const TypeKind TK_BITSET
Definition: TypeObject.h:245

◆ is_delimited_with_flags()

bool OpenDDS::XTypes::TypeAssignability::is_delimited_with_flags ( TypeFlag  flags) const
private

Definition at line 1859 of file TypeAssignability.cpp.

References OpenDDS::XTypes::IS_FINAL, and OpenDDS::XTypes::IS_MUTABLE.

Referenced by is_delimited().

1860 {
1861  if ((flags & IS_FINAL) == IS_FINAL) {
1862  return false;
1863  } else if ((flags & IS_MUTABLE) == IS_MUTABLE) {
1864  // Mutable types are delimited with both encoding versions 1 and 2
1865  return true;
1866  } else { // Default extensibility is APPENDABLE (7.3.1.2.1.8)
1867  // Types with extensibility kind APPENDABLE are delimited
1868  // if serialized with encoding version 2 and are not
1869  // delimited if serialized with encoding version 1.
1870  // We are supporting XCDR2 in this iteration.
1871  return true;
1872  }
1873 }
const TypeFlag IS_MUTABLE
Definition: TypeObject.h:402
const TypeFlag IS_FINAL
Definition: TypeObject.h:400

◆ lookup_minimal()

const MinimalTypeObject& OpenDDS::XTypes::TypeAssignability::lookup_minimal ( const TypeIdentifier ti) const
inlineprivate

◆ set_ignore_member_names()

void OpenDDS::XTypes::TypeAssignability::set_ignore_member_names ( bool  value)
inline

Definition at line 80 of file TypeAssignability.h.

References value.

81  {
83  }
const LogLevel::Value value
Definition: debug.cpp:61
TypeConsistencyAttributes type_consistency_

◆ set_ignore_sequence_bounds()

void OpenDDS::XTypes::TypeAssignability::set_ignore_sequence_bounds ( bool  value)
inline

Definition at line 68 of file TypeAssignability.h.

References value.

69  {
71  }
const LogLevel::Value value
Definition: debug.cpp:61
TypeConsistencyAttributes type_consistency_

◆ set_ignore_string_bounds()

void OpenDDS::XTypes::TypeAssignability::set_ignore_string_bounds ( bool  value)
inline

Definition at line 74 of file TypeAssignability.h.

References value.

75  {
77  }
const LogLevel::Value value
Definition: debug.cpp:61
TypeConsistencyAttributes type_consistency_

◆ set_prevent_type_widening()

void OpenDDS::XTypes::TypeAssignability::set_prevent_type_widening ( bool  value)
inline

Definition at line 62 of file TypeAssignability.h.

References value.

63  {
65  }
const LogLevel::Value value
Definition: debug.cpp:61
TypeConsistencyAttributes type_consistency_

◆ strongly_assignable()

bool OpenDDS::XTypes::TypeAssignability::strongly_assignable ( const TypeIdentifier ta,
const TypeIdentifier tb 
) const
private

If types T1 and T2 are equivalent using the MINIMAL relation, or alternatively if T1 is-assignable-from T2 and T2 is a delimited type, then T1 is said to be strongly assignable from T2.

Definition at line 1590 of file TypeAssignability.cpp.

References assignable(), equal_type_id(), and is_delimited().

Referenced by assignable_array(), assignable_map(), assignable_plain_array(), assignable_plain_map(), assignable_plain_sequence(), assignable_sequence(), assignable_struct(), and assignable_union().

1592 {
1593  if (equal_type_id(tia, tib)) {
1594  return true;
1595  }
1596 
1597  if (assignable(tia, tib) && is_delimited(tib)) {
1598  return true;
1599  }
1600  return false;
1601 }
bool is_delimited(const TypeIdentifier &ti) const
Concept of delimited types (sub-clause 7.2.4.2)
bool equal_type_id(const TypeIdentifier &tia, const TypeIdentifier &tib) const
Check whether two type identifiers are equal.
bool assignable(const TypeObject &ta, const TypeObject &tb) const
Both input type objects must be minimal.

◆ struct_rule_enum_key()

bool OpenDDS::XTypes::TypeAssignability::struct_rule_enum_key ( const MinimalTypeObject tb,
const CommonStructMember ma 
) const
private

The first argument must be TK_ENUM and is the type object of a key member of the containing struct. Therefore, there must be a member with the same ID (and name) in the other struct type.

Definition at line 1997 of file TypeAssignability.cpp.

References OpenDDS::XTypes::EK_MINIMAL, OpenDDS::XTypes::MinimalTypeObject::enumerated_type, get_base_type(), OpenDDS::XTypes::TypeIdentifier::kind(), OpenDDS::XTypes::MinimalTypeObject::kind, OpenDDS::XTypes::MinimalEnumeratedType::literal_seq, lookup_minimal(), OpenDDS::XTypes::CommonStructMember::member_type_id, OpenDDS::XTypes::Sequence< T >::members, OpenDDS::XTypes::TK_ALIAS, and OpenDDS::XTypes::TK_ENUM.

Referenced by assignable_struct().

1999 {
2000  if (EK_MINIMAL != ma.member_type_id.kind()) {
2001  return false;
2002  }
2003 
2004  const MinimalEnumeratedLiteralSeq& literals_b = tb.enumerated_type.literal_seq;
2005  const MinimalTypeObject& toa = lookup_minimal(ma.member_type_id);
2006  const MinimalEnumeratedLiteralSeq* literals_a = 0;
2007  if (TK_ENUM == toa.kind) {
2008  literals_a = &toa.enumerated_type.literal_seq;
2009  } else if (TK_ALIAS == toa.kind) {
2010  const TypeIdentifier& base_a = get_base_type(toa);
2011  if (EK_MINIMAL == base_a.kind()) {
2012  const MinimalTypeObject& base_obj_a = lookup_minimal(base_a);
2013  if (TK_ENUM == base_obj_a.kind) {
2014  literals_a = &base_obj_a.enumerated_type.literal_seq;
2015  } else {
2016  return false;
2017  }
2018  } else {
2019  return false;
2020  }
2021  } else {
2022  return false;
2023  }
2024 
2025  // All literals in tb must appear as literals in toa
2026  for (size_t j = 0; j < literals_b.members.size(); ++j) {
2027  const NameHash& h_b = literals_b.members[j].detail.name_hash;
2028  ACE_CDR::ULong key_b = (h_b[0] << 24) | (h_b[1] << 16) | (h_b[2] << 8) | (h_b[3]);
2029  bool found = false;
2030  for (size_t k = 0; k < literals_a->members.size(); ++k) {
2031  const NameHash& h_a = literals_a->members[k].detail.name_hash;
2032  ACE_CDR::ULong key_a = (h_a[0] << 24) | (h_a[1] << 16) | (h_a[2] << 8) | (h_a[3]);
2033  if (key_a == key_b) {
2034  found = true;
2035  break;
2036  }
2037  }
2038  if (!found) {
2039  return false;
2040  }
2041  }
2042  return true;
2043 }
const MinimalTypeObject & lookup_minimal(const TypeIdentifier &ti) const
const TypeIdentifier & get_base_type(const MinimalTypeObject &type) const
The input must be of type TK_ALIAS Return the non-alias base type identifier of the input...
ACE_UINT32 ULong
const TypeKind TK_ALIAS
Definition: TypeObject.h:235
const TypeKind TK_ENUM
Definition: TypeObject.h:238
const EquivalenceKind EK_MINIMAL
Definition: TypeObject.h:205
Sequence< MinimalEnumeratedLiteral > MinimalEnumeratedLiteralSeq
Definition: TypeObject.h:2567
ACE_CDR::Octet NameHash[4]
Definition: TypeObject.h:296

Member Data Documentation

◆ tl_service_

XTypes::TypeLookupService_rch OpenDDS::XTypes::TypeAssignability::tl_service_
private

Definition at line 147 of file TypeAssignability.h.

◆ type_consistency_

TypeConsistencyAttributes OpenDDS::XTypes::TypeAssignability::type_consistency_
private

Definition at line 152 of file TypeAssignability.h.

Referenced by assignable_struct(), and assignable_union().


The documentation for this class was generated from the following files: