NebulaGraph CPP Client  release-3.4
Value.h
1 /* Copyright (c) 2020 vesoft inc. All rights reserved.
2  *
3  * This source code is licensed under Apache 2.0 License.
4  */
5 
6 #pragma once
7 
8 #include <memory>
9 
10 #include "common/datatypes/Date.h"
11 #include "common/datatypes/Duration.h"
12 #include "common/thrift/ThriftTypes.h"
13 
14 namespace apache {
15 namespace thrift {
16 
17 template <class T, class U>
18 class Cpp2Ops;
19 
20 } // namespace thrift
21 } // namespace apache
22 
23 namespace nebula {
24 
25 struct Vertex;
26 struct Edge;
27 struct Path;
28 struct Map;
29 struct List;
30 struct Set;
31 struct DataSet;
32 struct Geography;
33 
34 enum class NullType {
35  __NULL__ = 0,
36  NaN = 1,
37  BAD_DATA = 2,
38  BAD_TYPE = 3,
39  ERR_OVERFLOW = 4,
40  UNKNOWN_PROP = 5,
41  DIV_BY_ZERO = 6,
42  OUT_OF_RANGE = 7,
43 };
44 
45 struct Value {
46  static const Value kEmpty;
47  static const Value kNullValue;
48  static const Value kNullNaN;
49  static const Value kNullBadData;
50  static const Value kNullBadType;
51  static const Value kNullOverflow;
52  static const Value kNullUnknownProp;
53  static const Value kNullDivByZero;
54  static const Value kNullOutOfRange;
55 
56  static const uint64_t kEmptyNullType;
57  static const uint64_t kNumericType;
58 
59  friend class apache::thrift::Cpp2Ops<Value, void>;
60 
61  enum class Type : uint64_t {
62  __EMPTY__ = 1UL,
63  BOOL = 1UL << 1,
64  INT = 1UL << 2,
65  FLOAT = 1UL << 3,
66  STRING = 1UL << 4,
67  DATE = 1UL << 5,
68  TIME = 1UL << 6,
69  DATETIME = 1UL << 7,
70  VERTEX = 1UL << 8,
71  EDGE = 1UL << 9,
72  PATH = 1UL << 10,
73  LIST = 1UL << 11,
74  MAP = 1UL << 12,
75  SET = 1UL << 13,
76  DATASET = 1UL << 14,
77  GEOGRAPHY = 1UL << 15,
78  DURATION = 1UL << 16,
79  NULLVALUE = 1UL << 63,
80  };
81 
82  // Constructors
83  Value() : type_(Type::__EMPTY__) {}
84  Value(Value&& rhs) noexcept;
85  Value(const Value& rhs);
86 
87  // For the cpp bool-pointer conversion, if Value ctor accept a pointer without
88  // matched ctor it will convert to bool type and the match the bool value
89  // ctor, So we disable all pointer ctor except the char*
90  template <typename T>
91  Value(T*) = delete; // NOLINT
92  Value(const std::nullptr_t) = delete; // NOLINT
93  Value(const NullType& v); // NOLINT
94  Value(NullType&& v); // NOLINT
95  Value(const bool& v); // NOLINT
96  Value(bool&& v); // NOLINT
97  Value(const int8_t& v); // NOLINT
98  Value(int8_t&& v); // NOLINT
99  Value(const int16_t& v); // NOLINT
100  Value(int16_t&& v); // NOLINT
101  Value(const int32_t& v); // NOLINT
102  Value(int32_t&& v); // NOLINT
103  Value(const int64_t& v); // NOLINT
104  Value(int64_t&& v); // NOLINT
105  Value(const double& v); // NOLINT
106  Value(double&& v); // NOLINT
107  Value(const std::string& v); // NOLINT
108  Value(std::string&& v); // NOLINT
109  Value(const char* v); // NOLINT
110  Value(const Date& v); // NOLINT
111  Value(Date&& v); // NOLINT
112  Value(const Time& v); // NOLINT
113  Value(Time&& v); // NOLINT
114  Value(const DateTime& v); // NOLINT
115  Value(DateTime&& v); // NOLINT
116  Value(const Vertex& v); // NOLINT
117  Value(Vertex&& v); // NOLINT
118  Value(const Edge& v); // NOLINT
119  Value(Edge&& v); // NOLINT
120  Value(const Path& v); // NOLINT
121  Value(Path&& v); // NOLINT
122  Value(const List& v); // NOLINT
123  Value(List&& v); // NOLINT
124  Value(const Map& v); // NOLINT
125  Value(Map&& v); // NOLINT
126  Value(const Set& v); // NOLINT
127  Value(Set&& v); // NOLINT
128  Value(const DataSet& v); // NOLINT
129  Value(DataSet&& v); // NOLINT
130  Value(const Geography& v); // NOLINT
131  Value(Geography&& v); // NOLINT
132  Value(const Duration& v); // NOLINT
133  Value(Duration&& v); // NOLINT
134  ~Value() {
135  clear();
136  }
137 
138  Type type() const noexcept {
139  return type_;
140  }
141 
142  const std::string& typeName() const;
143  static const std::string toString(Type type);
144 
145  bool empty() const {
146  return type_ == Type::__EMPTY__;
147  }
148  bool isNull() const {
149  return type_ == Type::NULLVALUE;
150  }
151  bool isBadNull() const {
152  if (!isNull()) {
153  return false;
154  }
155  auto& null = value_.nVal;
156  return null == NullType::NaN || null == NullType::BAD_DATA || null == NullType::BAD_TYPE ||
157  null == NullType::ERR_OVERFLOW || null == NullType::UNKNOWN_PROP ||
158  null == NullType::DIV_BY_ZERO || null == NullType::OUT_OF_RANGE;
159  }
160  bool isNumeric() const {
161  return type_ == Type::INT || type_ == Type::FLOAT;
162  }
163  bool isBool() const {
164  return type_ == Type::BOOL;
165  }
166  bool isInt() const {
167  return type_ == Type::INT;
168  }
169  bool isFloat() const {
170  return type_ == Type::FLOAT;
171  }
172  bool isStr() const {
173  return type_ == Type::STRING;
174  }
175  bool isDate() const {
176  return type_ == Type::DATE;
177  }
178  bool isTime() const {
179  return type_ == Type::TIME;
180  }
181  bool isDateTime() const {
182  return type_ == Type::DATETIME;
183  }
184  bool isVertex() const {
185  return type_ == Type::VERTEX;
186  }
187  bool isEdge() const {
188  return type_ == Type::EDGE;
189  }
190  bool isPath() const {
191  return type_ == Type::PATH;
192  }
193  bool isList() const {
194  return type_ == Type::LIST;
195  }
196  bool isMap() const {
197  return type_ == Type::MAP;
198  }
199  bool isSet() const {
200  return type_ == Type::SET;
201  }
202  bool isDataSet() const {
203  return type_ == Type::DATASET;
204  }
205  bool isGeography() const {
206  return type_ == Type::GEOGRAPHY;
207  }
208  bool isDuration() const {
209  return type_ == Type::DURATION;
210  }
211 
212  void clear();
213 
214  void __clear() {
215  clear();
216  }
217 
218  Value& operator=(Value&& rhs) noexcept;
219  Value& operator=(const Value& rhs);
220 
221  void setNull(const NullType& v);
222  void setNull(NullType&& v);
223  void setBool(const bool& v);
224  void setBool(bool&& v);
225  void setInt(const int8_t& v);
226  void setInt(int8_t&& v);
227  void setInt(const int16_t& v);
228  void setInt(int16_t&& v);
229  void setInt(const int32_t& v);
230  void setInt(int32_t&& v);
231  void setInt(const int64_t& v);
232  void setInt(int64_t&& v);
233  void setFloat(const double& v);
234  void setFloat(double&& v);
235  void setStr(const std::string& v);
236  void setStr(std::string&& v);
237  void setStr(const char* v);
238  void setDate(const Date& v);
239  void setDate(Date&& v);
240  void setTime(const Time& v);
241  void setTime(Time&& v);
242  void setDateTime(const DateTime& v);
243  void setDateTime(DateTime&& v);
244  void setVertex(const Vertex& v);
245  void setVertex(Vertex&& v);
246  void setVertex(std::unique_ptr<Vertex>&& v);
247  void setEdge(const Edge& v);
248  void setEdge(Edge&& v);
249  void setEdge(std::unique_ptr<Edge>&& v);
250  void setPath(const Path& v);
251  void setPath(Path&& v);
252  void setPath(std::unique_ptr<Path>&& v);
253  void setList(const List& v);
254  void setList(List&& v);
255  void setList(std::unique_ptr<List>&& v);
256  void setMap(const Map& v);
257  void setMap(Map&& v);
258  void setMap(std::unique_ptr<Map>&& v);
259  void setSet(const Set& v);
260  void setSet(Set&& v);
261  void setSet(std::unique_ptr<Set>&& v);
262  void setDataSet(const DataSet& v);
263  void setDataSet(DataSet&& v);
264  void setDataSet(std::unique_ptr<DataSet>&& v);
265  void setGeography(const Geography& v);
266  void setGeography(Geography&& v);
267  void setGeography(std::unique_ptr<Geography>&& v);
268  void setDuration(const Duration& v);
269  void setDuration(Duration&& v);
270  void setDuration(std::unique_ptr<Duration>&& v);
271 
272  const NullType& getNull() const;
273  const bool& getBool() const;
274  const int64_t& getInt() const;
275  const double& getFloat() const;
276  const std::string& getStr() const;
277  const Date& getDate() const;
278  const Time& getTime() const;
279  const DateTime& getDateTime() const;
280  const Vertex& getVertex() const;
281  const Vertex* getVertexPtr() const;
282  const Edge& getEdge() const;
283  const Edge* getEdgePtr() const;
284  const Path& getPath() const;
285  const Path* getPathPtr() const;
286  const List& getList() const;
287  const List* getListPtr() const;
288  const Map& getMap() const;
289  const Map* getMapPtr() const;
290  const Set& getSet() const;
291  const Set* getSetPtr() const;
292  const DataSet& getDataSet() const;
293  const DataSet* getDataSetPtr() const;
294  const Geography& getGeography() const;
295  const Geography* getGeographyPtr() const;
296  const Duration& getDuration() const;
297  const Duration* getDurationPtr() const;
298 
299  NullType moveNull();
300  bool moveBool();
301  int64_t moveInt();
302  double moveFloat();
303  std::string moveStr();
304  Date moveDate();
305  Time moveTime();
306  DateTime moveDateTime();
307  Vertex moveVertex();
308  Edge moveEdge();
309  Path movePath();
310  List moveList();
311  Map moveMap();
312  Set moveSet();
313  DataSet moveDataSet();
314  Geography moveGeography();
315  Duration moveDuration();
316 
317  NullType& mutableNull();
318  bool& mutableBool();
319  int64_t& mutableInt();
320  double& mutableFloat();
321  std::string& mutableStr();
322  Date& mutableDate();
323  Time& mutableTime();
324  DateTime& mutableDateTime();
325  Vertex& mutableVertex();
326  Edge& mutableEdge();
327  Path& mutablePath();
328  List& mutableList();
329  Map& mutableMap();
330  Set& mutableSet();
331  DataSet& mutableDataSet();
332  Geography& mutableGeography();
333  Duration& mutableDuration();
334 
335  static const Value& null() noexcept {
336  return kNullValue;
337  }
338 
339  std::string toString() const;
340 
341  Value toBool() const;
342  Value toFloat() const;
343  Value toInt() const;
344 
345  Value lessThan(const Value& v) const;
346 
347  Value equal(const Value& v) const;
348 
349  private:
350  Type type_;
351 
352  union Storage {
353  NullType nVal;
354  bool bVal;
355  int64_t iVal;
356  double fVal;
357  std::unique_ptr<std::string> sVal;
358  Date dVal;
359  Time tVal;
360  DateTime dtVal;
361  std::unique_ptr<Vertex> vVal;
362  std::unique_ptr<Edge> eVal;
363  std::unique_ptr<Path> pVal;
364  std::unique_ptr<List> lVal;
365  std::unique_ptr<Map> mVal;
366  std::unique_ptr<Set> uVal;
367  std::unique_ptr<DataSet> gVal;
368  std::unique_ptr<Geography> ggVal;
369  std::unique_ptr<Duration> duVal;
370 
371  Storage() {}
372  ~Storage() {}
373  } value_;
374 
375  template <class T>
376  void destruct(T& val) {
377  (&val)->~T();
378  }
379 
380  // Null value
381  void setN(const NullType& v);
382  void setN(NullType&& v);
383  // Bool value
384  void setB(const bool& v);
385  void setB(bool&& v);
386  // Integer value
387  void setI(const int64_t& v);
388  void setI(int64_t&& v);
389  // Double float value
390  void setF(const double& v);
391  void setF(double&& v);
392  // String value
393  void setS(const std::string& v);
394  void setS(std::string&& v);
395  void setS(const char* v);
396  void setS(std::unique_ptr<std::string> v);
397  // Date value
398  void setD(const Date& v);
399  void setD(Date&& v);
400  // Date value
401  void setT(const Time& v);
402  void setT(Time&& v);
403  // DateTime value
404  void setDT(const DateTime& v);
405  void setDT(DateTime&& v);
406  // Vertex value
407  void setV(const std::unique_ptr<Vertex>& v);
408  void setV(std::unique_ptr<Vertex>&& v);
409  void setV(const Vertex& v);
410  void setV(Vertex&& v);
411  // Edge value
412  void setE(const std::unique_ptr<Edge>& v);
413  void setE(std::unique_ptr<Edge>&& v);
414  void setE(const Edge& v);
415  void setE(Edge&& v);
416  // Path value
417  void setP(const std::unique_ptr<Path>& v);
418  void setP(std::unique_ptr<Path>&& v);
419  void setP(const Path& v);
420  void setP(Path&& v);
421  // List value
422  void setL(const std::unique_ptr<List>& v);
423  void setL(std::unique_ptr<List>&& v);
424  void setL(const List& v);
425  void setL(List&& v);
426  // Map value
427  void setM(const std::unique_ptr<Map>& v);
428  void setM(std::unique_ptr<Map>&& v);
429  void setM(const Map& v);
430  void setM(Map&& v);
431  // Set value
432  void setU(const std::unique_ptr<Set>& v);
433  void setU(std::unique_ptr<Set>&& v);
434  void setU(const Set& v);
435  void setU(Set&& v);
436  // DataSet value
437  void setG(const std::unique_ptr<DataSet>& v);
438  void setG(std::unique_ptr<DataSet>&& v);
439  void setG(const DataSet& v);
440  void setG(DataSet&& v);
441  // Geography value
442  void setGG(const std::unique_ptr<Geography>& v);
443  void setGG(std::unique_ptr<Geography>&& v);
444  void setGG(const Geography& v);
445  void setGG(Geography&& v);
446  // Duration value
447  void setDU(const std::unique_ptr<Duration>& v);
448  void setDU(std::unique_ptr<Duration>&& v);
449  void setDU(const Duration& v);
450  void setDU(Duration&& v);
451 };
452 
453 static_assert(sizeof(Value) == 16UL, "The size of Value should be 16UL");
454 
455 void swap(Value& a, Value& b);
456 
457 constexpr auto kEpsilon = 1e-8;
458 
459 // Arithmetic operations
460 Value operator+(const Value& lhs, const Value& rhs);
461 Value operator-(const Value& lhs, const Value& rhs);
462 Value operator*(const Value& lhs, const Value& rhs);
463 Value operator/(const Value& lhs, const Value& rhs);
464 Value operator%(const Value& lhs, const Value& rhs);
465 // Unary operations
466 Value operator-(const Value& rhs);
467 Value operator!(const Value& rhs);
468 // Comparison operations
469 // 1. we compare the type directly in these cases:
470 // if type do not match except both numeric
471 // if lhs and rhs have at least one null or empty
472 // 2. null is the biggest, empty is the smallest
473 bool operator<(const Value& lhs, const Value& rhs);
474 bool operator==(const Value& lhs, const Value& rhs);
475 bool operator!=(const Value& lhs, const Value& rhs);
476 bool operator>(const Value& lhs, const Value& rhs);
477 bool operator<=(const Value& lhs, const Value& rhs);
478 bool operator>=(const Value& lhs, const Value& rhs);
479 // Logical operations
480 Value operator&&(const Value& lhs, const Value& rhs);
481 Value operator||(const Value& lhs, const Value& rhs);
482 // Bit operations
483 Value operator&(const Value& lhs, const Value& rhs);
484 Value operator|(const Value& lhs, const Value& rhs);
485 Value operator^(const Value& lhs, const Value& rhs);
486 // Visualize
487 std::ostream& operator<<(std::ostream& os, const Value::Type& type);
488 inline std::ostream& operator<<(std::ostream& os, const Value& value) {
489  return os << value.toString();
490 }
491 
492 inline uint64_t operator|(const Value::Type& lhs, const Value::Type& rhs) {
493  return static_cast<uint64_t>(lhs) | static_cast<uint64_t>(rhs);
494 }
495 inline uint64_t operator|(const uint64_t lhs, const Value::Type& rhs) {
496  return lhs | static_cast<uint64_t>(rhs);
497 }
498 inline uint64_t operator|(const Value::Type& lhs, const uint64_t rhs) {
499  return static_cast<uint64_t>(lhs) | rhs;
500 }
501 inline uint64_t operator&(const Value::Type& lhs, const Value::Type& rhs) {
502  return static_cast<uint64_t>(lhs) & static_cast<uint64_t>(rhs);
503 }
504 inline uint64_t operator&(const uint64_t lhs, const Value::Type& rhs) {
505  return lhs & static_cast<uint64_t>(rhs);
506 }
507 inline uint64_t operator&(const Value::Type& lhs, const uint64_t rhs) {
508  return static_cast<uint64_t>(lhs) & rhs;
509 }
510 
511 } // namespace nebula
512 
513 namespace std {
514 
515 // Inject a customized hash function
516 template <>
517 struct hash<nebula::Value> {
518  std::size_t operator()(const nebula::Value& h) const noexcept;
519 };
520 
521 template <>
522 struct hash<nebula::Value*> {
523  std::size_t operator()(const nebula::Value* h) const noexcept {
524  return h == nullptr ? 0 : hash<nebula::Value>()(*h);
525  }
526 };
527 
528 template <>
529 struct equal_to<nebula::Value*> {
530  bool operator()(const nebula::Value* lhs, const nebula::Value* rhs) const noexcept {
531  return lhs == rhs ? true : (lhs != nullptr) && (rhs != nullptr) && (*lhs == *rhs);
532  }
533 };
534 
535 } // namespace std