StreamBase C++ API  7.7.8.2
CompleteDataType.hpp
1 //
2 // Copyright (c) 2004-2019 TIBCO Software Inc. All rights reserved.
3 //
4 
5 #ifndef STREAMBASE_COMPLETEDATATYPE_HPP_
6 #define STREAMBASE_COMPLETEDATATYPE_HPP_
7 
8 #include "StreamBase.hpp"
9 
10 #include "DataType.hpp"
11 #include "Schema.hpp"
12 
13 SB_NAMESPACE_BEGIN;
14 
15 class Schema;
16 
17 /** An object containing all the information about a data type -- the primitive DataType;
18  * for DataType::TUPLEs, the Tuple's Schema; and for DataType::LISTs, the List elements'
19  * own CompleteDataType.
20  *
21  * To get a CompleteDataType object, call the type-appropriate static method, eg. for a
22  * Boolean CompleteDatatType object, call CompleteDataType::forBool(); for a Tuple CompleteDataType,
23  * call CompleteDataType::forTuple(s) with some Schema s; for a List CompleteDataType, call
24  * CompleteDataType::forList(cdt) with some CompleteDataType cdt; and so on.
25  *
26  * CompleteDataTypes are immutable; once created they may not be changed.
27  */
29 {
30 private:
31  /**
32  * Create a complete data type from a DataType::foo enum value
33  */
34  CompleteDataType(DataType type) : _type(type), _schema(0), _name(""), _cdt(0) { }
35 
36 
37  /**
38  * Create a complete data type of DataType::TUPLE with the specified Schema
39  */
40  CompleteDataType(const Schema &schema) : _type(DataType::TUPLE), _schema(new Schema(schema)), _name(""), _cdt(0), _argumentSchema(0), _returnType(0) { }
41 
42  /**
43  * Creates a complete data type of the given type. Errors if given a schema for a non-DataType::TUPLE type.
44  */
45  CompleteDataType(DataType type, const Schema &schema) : _type(type), _schema(new Schema(schema)), _name(""), _cdt(0), _argumentSchema(0), _returnType(0) {
46  assert(!schema || type == DataType::TUPLE);
47  }
48 
49  /**
50  * Create a complete data type of type1 with sub-type type2,
51  * eg CompleteDataType(DataType::LIST, DataType::INT)
52  */
53  CompleteDataType(DataType type, DataType elementType) :
54  _type(type), _schema(0), _name(""), _cdt(new CompleteDataType(elementType)), _argumentSchema(0), _returnType(0) {
55  assert(type == DataType::LIST);
56  }
57 
58  /**
59  * Create a complete data type of type1 with sub-complete data type type2,
60  * eg CompleteDataType(DataType::LIST, CompleteDataType(DataType::LIST, DataType::INT))
61  */
62  CompleteDataType(DataType type, const CompleteDataType& elementCDT) :
63  _type(type), _schema(0), _name(""), _cdt(new CompleteDataType(elementCDT)), _argumentSchema(0), _returnType(0) {
64  assert(type == DataType::LIST);
65  }
66 
67  /**
68  * Create a complete data type for a capture field with the given name. type must be DataType::CAPTURE
69  */
70  CompleteDataType(DataType type, const std::string name) :
71  _type(type), _schema(0), _name(name), _cdt(0), _argumentSchema(0), _returnType(0) {
72  assert(type == DataType::CAPTURE);
73  }
74 
75  /**
76  * Create a complete data type for a function with the given argument schema and return type
77  */
78  CompleteDataType(DataType type, const Schema& argumentSchema, const CompleteDataType& returnType) :
79  _type(type), _schema(0), _name(""), _cdt(0), _argumentSchema(new Schema(argumentSchema)), _returnType(new CompleteDataType(returnType)) {
80  assert(type == DataType::FUNCTION);
81  }
82 
83 
84 public:
85 #ifndef DOXYGEN_INTERNAL_ONLY
86  /// Null constructor
87  CompleteDataType() : _type(DataType::NONE), _schema(0), _cdt(0), _argumentSchema(0), _returnType(0) {}
88 #endif
89 
90  /// Copy constructor
91  CompleteDataType(const CompleteDataType& cdt) : _type(cdt._type),
92  _schema(cdt._schema ? new Schema(*(cdt._schema)) : 0),
93  _name(cdt._name),
94  _cdt(cdt._cdt ? new CompleteDataType(*(cdt._cdt)) : 0),
95  _argumentSchema(cdt._argumentSchema ? new Schema(*(cdt._argumentSchema)) : 0),
96  _returnType(cdt._returnType ? new CompleteDataType(*(cdt._returnType)) : 0){
97  }
98 
99  /// Assignment operator
100  CompleteDataType& operator=(const CompleteDataType& cdt);
101 
102  /// Destructor
104  delete _schema;
105  delete _cdt;
106  }
107 
108  // Comparison operators
109  bool operator==(const CompleteDataType& t) const { return compare(t) == 0; }
110  bool operator!=(const CompleteDataType& t) const { return compare(t) != 0; }
111  bool operator<(const CompleteDataType& t) const { return compare(t) < 0; }
112  bool operator>(const CompleteDataType& t) const { return compare(t) > 0; }
113  bool operator<=(const CompleteDataType& t) const { return compare(t) <= 0; }
114  bool operator>=(const CompleteDataType& t) const { return compare(t) >= 0; }
115 
116  // void * operator
117  operator const void *() const { return this; }
118 
119  /**
120  * Compare the current CompleteDataType against the provided CompleteDataType by
121  * base type (eg DataType::BOOL, ::INT, ::TUPLE, etc). Therefore,
122  * for example a LIST of type INT and a LIST of type TUPLE are equal.
123  *
124  * @return -1 if the current CompleteDataType is less than the provided CompleteDataType,
125  * 0 if the current is equal to the provided CompleteDataType,
126  * and 1 if the current is greater than the provided CompleteDataType.
127  */
128  int compare(const CompleteDataType& fv) const;
129 
130  /// Return a CompleteDataType of type DataType::BOOL
131  static const CompleteDataType &forBool() { return BOOL; }
132  /// Return a CompleteDataType of type DataType::INT
133  static const CompleteDataType &forInt() { return INT; }
134  /// Return a CompleteDataType of type DataType::LONG
135  static const CompleteDataType &forLong() { return LONG; }
136  /// Return a CompleteDataType of type DataType::DOUBLE
137  static const CompleteDataType &forDouble() { return DOUBLE; }
138  /// Return a CompleteDataType of type DataType::TIMESTAMP
139  static const CompleteDataType &forTimestamp() { return TIMESTAMP; }
140  /// Return a CompleteDataType of type DataType::STRING
141  static const CompleteDataType &forString() { return STRING; }
142  /// Return a CompleteDataType of type DataType::BLOB
143  static const CompleteDataType &forBlob() { return BLOB; }
144  /// Return a CompleteDataType of type DataType::TUPLE with the given Schema
145  static const CompleteDataType forTuple(const Schema& s) { return CompleteDataType(DataType::TUPLE, s); }
146  /// Return a CompleteDataType of type DataType::LIST with the given CompleteDataType as the type of its elements
147  static const CompleteDataType forList(const CompleteDataType& elemType) { return CompleteDataType(DataType::LIST, elemType); }
148  /// Return a CompleteDataType of type DataType::CAPTURE with the given capture type name
149  static const CompleteDataType forCapture(const std::string &captureName) { return CompleteDataType(DataType::CAPTURE, captureName); }
150  /// Return a CompleteDataType of type DataType::FUNCTION with the given argument schema and return type
151  static const CompleteDataType forFunction(const Schema& argumentSchema, const CompleteDataType& returnType) {
152  return CompleteDataType(DataType::FUNCTION, argumentSchema, returnType);
153  }
154 
155  /// Convenience method. Return the CompleteDataType appropriate to the given DataType. Invalid on DataType::TUPLE
156  /// and DataType::LIST, since they require extra information to fully specify their CompleteDataType.
157  static const CompleteDataType forSimpleType(const DataType& type);
158 
159  /**
160  * Return the primitive DataType of the CompleteDataType.
161  */
162  const DataType &getType() const {
163  return _type;
164  }
165 
166  /**
167  * Returns true if this CompleteDataType contains a Schema (eg it is a DataType::TUPLE).
168  */
169  bool hasSchema() {
170  return _type == DataType::TUPLE;
171  }
172 
173  /**
174  * If this CompleteDataType has a nested tuple, return its Schema. For all other types, return a null Schema.
175  */
176  const Schema getSchema() const {
177  return _schema ? *_schema : Schema::EMPTY_SCHEMA;
178  }
179 
180  /**
181  * Returns true if this CompleteDataType has an element CompleteDataType (eg it is a DataType::LIST of DataType::INTs, the latter being its element type).
182  */
183  bool hasElementType() const {
184  return _cdt ? _cdt->getType() != DataType::NONE : false;
185  }
186 
187  /**
188  * If this CompleteDataType has an element type, returns the element CompleteDataType. For all other types, returns a null CompleteDataType.
189  */
191  return _cdt ? *_cdt : EMPTY_DATATYPE;
192  }
193 
194  /**
195  * If this CompleteDataType is a function, return its return type
196  */
198  return _returnType ? *_returnType : EMPTY_DATATYPE;
199  }
200 
201 
202  /**
203  * If this CompleteDataType is a function, return its argument schema
204  */
205  const Schema& getArgumentSchema() const {
206  return _argumentSchema ? *_argumentSchema : Schema::EMPTY_SCHEMA;
207  }
208 
209  std::string getCaptureTypeName() const {
210  return _name;
211  }
212 
213  /**
214  * Returns a string representation of this CompleteDataType.
215  */
216  std::string as_string() const {
217  switch(_type) {
218  case DataType::NONE:
219  case DataType::BOOL:
220  case DataType::INT:
221  case DataType::LONG:
222  case DataType::DOUBLE:
223  case DataType::TIMESTAMP:
224  case DataType::STRING:
225  case DataType::BLOB:
226  return NMSTL::to_string(_type);
227  case DataType::TUPLE:
228  return NMSTL::to_string(_type) + " (" + NMSTL::to_string(getSchema()) + ")";
229  case DataType::LIST:
230  return NMSTL::to_string(_type) + " (" + NMSTL::to_string(getElementCompleteType()) + ")";
231  case DataType::CAPTURE:
232  return "@" + _name;
233  case DataType::FUNCTION:
234  assert (_argumentSchema && _returnType);
235  return _argumentSchema->as_string() + " -> " + _returnType->as_string();
236  }
237 
238  NMSTL_ASSERT_UNREACHABLE();
239  }
240 
241 private:
242  static const CompleteDataType EMPTY_DATATYPE;
243  static const CompleteDataType BOOL;
244  static const CompleteDataType INT;
245  static const CompleteDataType LONG;
246  static const CompleteDataType DOUBLE;
247  static const CompleteDataType TIMESTAMP;
248  static const CompleteDataType STRING;
249  static const CompleteDataType BLOB;
250  DataType _type;
251  Schema *_schema; // schema for tuples
252  std::string _name; // name for capture types
253  CompleteDataType *_cdt; // CDT for list elements
254  Schema *_argumentSchema;
255  CompleteDataType *_returnType;
256 };
257 
258 SB_NAMESPACE_END;
259 
260 #endif /*STREAMBASE_COMPLETEDATATYPE_HPP_*/