diff options
author | Devtools Arcadia <arcadia-devtools@yandex-team.ru> | 2022-02-07 18:08:42 +0300 |
---|---|---|
committer | Devtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net> | 2022-02-07 18:08:42 +0300 |
commit | 1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch) | |
tree | e26c9fed0de5d9873cce7e00bc214573dc2195b7 /library/cpp/yson_pull/scalar.h | |
download | ydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz |
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'library/cpp/yson_pull/scalar.h')
-rw-r--r-- | library/cpp/yson_pull/scalar.h | 146 |
1 files changed, 146 insertions, 0 deletions
diff --git a/library/cpp/yson_pull/scalar.h b/library/cpp/yson_pull/scalar.h new file mode 100644 index 00000000000..509fce8b5ec --- /dev/null +++ b/library/cpp/yson_pull/scalar.h @@ -0,0 +1,146 @@ +#pragma once + +#include "cyson_enums.h" + +#include <util/generic/strbuf.h> +#include <util/system/types.h> +#include <util/system/yassert.h> + +namespace NYsonPull { + //! \brief YSON TScalar value type tag + enum class EScalarType { + Entity = YSON_SCALAR_ENTITY, + Boolean = YSON_SCALAR_BOOLEAN, + Int64 = YSON_SCALAR_INT64, + UInt64 = YSON_SCALAR_UINT64, + Float64 = YSON_SCALAR_FLOAT64, + String = YSON_SCALAR_STRING, + }; + + //! \brief YSON TScalar value variant + class TScalar { + //! \internal \brief YSON TScalar value underlying representation + union TScalarValue { + struct TScalarStringRef { + const char* Data; + size_t Size; + }; + + ui8 AsNothing[1]; + bool AsBoolean; + i64 AsInt64; + ui64 AsUInt64; + double AsFloat64; + TScalarStringRef AsString; + + constexpr TScalarValue() + : AsNothing{} { + } + + explicit constexpr TScalarValue(bool value) + : AsBoolean{value} { + } + + explicit constexpr TScalarValue(i64 value) + : AsInt64{value} { + } + + explicit constexpr TScalarValue(ui64 value) + : AsUInt64{value} { + } + + explicit constexpr TScalarValue(double value) + : AsFloat64{value} { + } + + explicit constexpr TScalarValue(TStringBuf value) + : AsString{value.data(), value.size()} { + } + }; + static_assert( + sizeof(TScalarValue) == sizeof(TStringBuf), + "bad scalar_value size"); + + EScalarType Type_; + TScalarValue Value_; + + public: + constexpr TScalar() + : Type_{EScalarType::Entity} { + } + + explicit constexpr TScalar(bool value) + : Type_{EScalarType::Boolean} + , Value_{value} { + } + + explicit constexpr TScalar(i64 value) + : Type_{EScalarType::Int64} + , Value_{value} { + } + + explicit constexpr TScalar(ui64 value) + : Type_{EScalarType::UInt64} + , Value_{value} { + } + + explicit constexpr TScalar(double value) + : Type_{EScalarType::Float64} + , Value_{value} { + } + + explicit constexpr TScalar(TStringBuf value) + : Type_{EScalarType::String} + , Value_{value} { + } + + // Disambiguation for literal constants + // In the absence of this constructor, + // they get implicitly converted to bool (yikes!) + explicit TScalar(const char* value) + : Type_{EScalarType::String} + , Value_{TStringBuf{value}} { + } + + EScalarType Type() const { + return Type_; + } + +#define CAST_TO(Type) \ + Y_ASSERT(Type_ == EScalarType::Type); \ + return Value_.As##Type + + bool AsBoolean() const { + CAST_TO(Boolean); + } + i64 AsInt64() const { + CAST_TO(Int64); + } + ui64 AsUInt64() const { + CAST_TO(UInt64); + } + double AsFloat64() const { + CAST_TO(Float64); + } +#undef CAST_TO + + TStringBuf AsString() const { + Y_ASSERT(Type_ == EScalarType::String); + return TStringBuf{ + Value_.AsString.Data, + Value_.AsString.Size, + }; + } + + const TScalarValue& AsUnsafeValue() const { + return Value_; + } + }; + + bool operator==(const TScalar& left, const TScalar& right) noexcept; + + inline bool operator!=(const TScalar& left, const TScalar& right) noexcept { + return !(left == right); + } + +} |