scalar.h 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. #pragma once
  2. #include "cyson_enums.h"
  3. #include <util/generic/strbuf.h>
  4. #include <util/system/types.h>
  5. #include <util/system/yassert.h>
  6. namespace NYsonPull {
  7. //! \brief YSON TScalar value type tag
  8. enum class EScalarType {
  9. Entity = YSON_SCALAR_ENTITY,
  10. Boolean = YSON_SCALAR_BOOLEAN,
  11. Int64 = YSON_SCALAR_INT64,
  12. UInt64 = YSON_SCALAR_UINT64,
  13. Float64 = YSON_SCALAR_FLOAT64,
  14. String = YSON_SCALAR_STRING,
  15. };
  16. //! \brief YSON TScalar value variant
  17. class TScalar {
  18. //! \internal \brief YSON TScalar value underlying representation
  19. union TScalarValue {
  20. struct TScalarStringRef {
  21. const char* Data;
  22. size_t Size;
  23. };
  24. ui8 AsNothing[1];
  25. bool AsBoolean;
  26. i64 AsInt64;
  27. ui64 AsUInt64;
  28. double AsFloat64;
  29. TScalarStringRef AsString;
  30. constexpr TScalarValue()
  31. : AsNothing{} {
  32. }
  33. explicit constexpr TScalarValue(bool value)
  34. : AsBoolean{value} {
  35. }
  36. explicit constexpr TScalarValue(i64 value)
  37. : AsInt64{value} {
  38. }
  39. explicit constexpr TScalarValue(ui64 value)
  40. : AsUInt64{value} {
  41. }
  42. explicit constexpr TScalarValue(double value)
  43. : AsFloat64{value} {
  44. }
  45. explicit constexpr TScalarValue(TStringBuf value)
  46. : AsString{value.data(), value.size()} {
  47. }
  48. };
  49. static_assert(
  50. sizeof(TScalarValue) == sizeof(TStringBuf),
  51. "bad scalar_value size");
  52. EScalarType Type_;
  53. TScalarValue Value_;
  54. public:
  55. constexpr TScalar()
  56. : Type_{EScalarType::Entity} {
  57. }
  58. explicit constexpr TScalar(bool value)
  59. : Type_{EScalarType::Boolean}
  60. , Value_{value} {
  61. }
  62. explicit constexpr TScalar(i64 value)
  63. : Type_{EScalarType::Int64}
  64. , Value_{value} {
  65. }
  66. explicit constexpr TScalar(ui64 value)
  67. : Type_{EScalarType::UInt64}
  68. , Value_{value} {
  69. }
  70. explicit constexpr TScalar(double value)
  71. : Type_{EScalarType::Float64}
  72. , Value_{value} {
  73. }
  74. explicit constexpr TScalar(TStringBuf value)
  75. : Type_{EScalarType::String}
  76. , Value_{value} {
  77. }
  78. // Disambiguation for literal constants
  79. // In the absence of this constructor,
  80. // they get implicitly converted to bool (yikes!)
  81. explicit TScalar(const char* value)
  82. : Type_{EScalarType::String}
  83. , Value_{TStringBuf{value}} {
  84. }
  85. EScalarType Type() const {
  86. return Type_;
  87. }
  88. #define CAST_TO(Type) \
  89. Y_ASSERT(Type_ == EScalarType::Type); \
  90. return Value_.As##Type
  91. bool AsBoolean() const {
  92. CAST_TO(Boolean);
  93. }
  94. i64 AsInt64() const {
  95. CAST_TO(Int64);
  96. }
  97. ui64 AsUInt64() const {
  98. CAST_TO(UInt64);
  99. }
  100. double AsFloat64() const {
  101. CAST_TO(Float64);
  102. }
  103. #undef CAST_TO
  104. TStringBuf AsString() const {
  105. Y_ASSERT(Type_ == EScalarType::String);
  106. return TStringBuf{
  107. Value_.AsString.Data,
  108. Value_.AsString.Size,
  109. };
  110. }
  111. const TScalarValue& AsUnsafeValue() const {
  112. return Value_;
  113. }
  114. };
  115. bool operator==(const TScalar& left, const TScalar& right) noexcept;
  116. inline bool operator!=(const TScalar& left, const TScalar& right) noexcept {
  117. return !(left == right);
  118. }
  119. }