aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/yson_pull/scalar.h
diff options
context:
space:
mode:
authorDevtools Arcadia <arcadia-devtools@yandex-team.ru>2022-02-07 18:08:42 +0300
committerDevtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net>2022-02-07 18:08:42 +0300
commit1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch)
treee26c9fed0de5d9873cce7e00bc214573dc2195b7 /library/cpp/yson_pull/scalar.h
downloadydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'library/cpp/yson_pull/scalar.h')
-rw-r--r--library/cpp/yson_pull/scalar.h146
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);
+ }
+
+}