udf_value_inl.h 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898
  1. #pragma once
  2. #if !defined(INCLUDE_UDF_VALUE_INL_H)
  3. #error "you should never include udf_value_inl.h directly"
  4. #endif // INCLUDE_UDF_VALUE_INL_H
  5. #ifdef LLVM_BC
  6. #define UDF_VERIFY(expr, ...) \
  7. do { \
  8. if (false) { \
  9. bool __xxx = static_cast<bool>(expr); \
  10. Y_UNUSED(__xxx); \
  11. } \
  12. } while (false)
  13. #define UDF_ALWAYS_INLINE __attribute__((always_inline))
  14. #else
  15. #define UDF_VERIFY Y_DEBUG_ABORT_UNLESS
  16. #define UDF_ALWAYS_INLINE Y_FORCE_INLINE
  17. #endif
  18. //////////////////////////////////////////////////////////////////////////////
  19. // IBoxedValue
  20. //////////////////////////////////////////////////////////////////////////////
  21. inline void IBoxedValue1::Ref() noexcept
  22. {
  23. #if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 4)
  24. if (Refs_ < 0)
  25. return;
  26. #endif
  27. ++Refs_;
  28. }
  29. inline void IBoxedValue1::UnRef() noexcept
  30. {
  31. #if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 4)
  32. if (Refs_ < 0)
  33. return;
  34. #endif
  35. Y_DEBUG_ABORT_UNLESS(Refs_ > 0);
  36. if (!--Refs_)
  37. delete this;
  38. }
  39. inline void IBoxedValue1::ReleaseRef() noexcept
  40. {
  41. #if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 4)
  42. if (Refs_ < 0)
  43. return;
  44. #endif
  45. Y_DEBUG_ABORT_UNLESS(Refs_ > 0);
  46. --Refs_;
  47. }
  48. inline void IBoxedValue1::DeleteUnreferenced() noexcept
  49. {
  50. if (!Refs_)
  51. delete this;
  52. }
  53. inline i32 IBoxedValue1::RefCount() const noexcept
  54. {
  55. return Refs_;
  56. }
  57. inline void IBoxedValue1::SetUserMark(ui8 mark) noexcept {
  58. UserMark_ = mark;
  59. }
  60. inline ui8 IBoxedValue1::UserMark() const noexcept {
  61. return UserMark_;
  62. }
  63. inline i32 IBoxedValue1::LockRef() noexcept {
  64. Y_DEBUG_ABORT_UNLESS(Refs_ != -1);
  65. auto ret = Refs_;
  66. Refs_ = -1;
  67. return ret;
  68. }
  69. inline void IBoxedValue1::UnlockRef(i32 prev) noexcept {
  70. Y_DEBUG_ABORT_UNLESS(Refs_ == -1);
  71. Y_DEBUG_ABORT_UNLESS(prev != -1);
  72. Refs_ = prev;
  73. }
  74. //////////////////////////////////////////////////////////////////////////////
  75. // TBoxedValueAccessor
  76. //////////////////////////////////////////////////////////////////////////////
  77. inline bool TBoxedValueAccessor::HasFastListLength(const IBoxedValue& value) {
  78. Y_DEBUG_ABORT_UNLESS(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
  79. return value.HasFastListLength();
  80. }
  81. inline ui64 TBoxedValueAccessor::GetListLength(const IBoxedValue& value) {
  82. Y_DEBUG_ABORT_UNLESS(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
  83. return value.GetListLength();
  84. }
  85. inline ui64 TBoxedValueAccessor::GetEstimatedListLength(const IBoxedValue& value) {
  86. Y_DEBUG_ABORT_UNLESS(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
  87. return value.GetEstimatedListLength();
  88. }
  89. inline TUnboxedValue TBoxedValueAccessor::GetListIterator(const IBoxedValue& value) {
  90. Y_DEBUG_ABORT_UNLESS(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
  91. return value.GetListIterator();
  92. }
  93. inline const TOpaqueListRepresentation* TBoxedValueAccessor::GetListRepresentation(const IBoxedValue& value) {
  94. Y_DEBUG_ABORT_UNLESS(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
  95. return value.GetListRepresentation();
  96. }
  97. inline IBoxedValuePtr TBoxedValueAccessor::ReverseListImpl(const IBoxedValue& value, const IValueBuilder& builder) {
  98. Y_DEBUG_ABORT_UNLESS(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
  99. return value.ReverseListImpl(builder);
  100. }
  101. inline IBoxedValuePtr TBoxedValueAccessor::SkipListImpl(const IBoxedValue& value, const IValueBuilder& builder, ui64 count) {
  102. Y_DEBUG_ABORT_UNLESS(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
  103. return value.SkipListImpl(builder, count);
  104. }
  105. inline IBoxedValuePtr TBoxedValueAccessor::TakeListImpl(const IBoxedValue& value, const IValueBuilder& builder, ui64 count) {
  106. Y_DEBUG_ABORT_UNLESS(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
  107. return value.TakeListImpl(builder, count);
  108. }
  109. inline IBoxedValuePtr TBoxedValueAccessor::ToIndexDictImpl(const IBoxedValue& value, const IValueBuilder& builder) {
  110. Y_DEBUG_ABORT_UNLESS(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
  111. return value.ToIndexDictImpl(builder);
  112. }
  113. inline ui64 TBoxedValueAccessor::GetDictLength(const IBoxedValue& value) {
  114. Y_DEBUG_ABORT_UNLESS(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
  115. return value.GetDictLength();
  116. }
  117. inline TUnboxedValue TBoxedValueAccessor::GetDictIterator(const IBoxedValue& value) {
  118. Y_DEBUG_ABORT_UNLESS(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
  119. return value.GetDictIterator();
  120. }
  121. inline TUnboxedValue TBoxedValueAccessor::GetKeysIterator(const IBoxedValue& value) {
  122. Y_DEBUG_ABORT_UNLESS(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
  123. return value.GetKeysIterator();
  124. }
  125. inline TUnboxedValue TBoxedValueAccessor::GetPayloadsIterator(const IBoxedValue& value) {
  126. Y_DEBUG_ABORT_UNLESS(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
  127. return value.GetPayloadsIterator();
  128. }
  129. inline bool TBoxedValueAccessor::Contains(const IBoxedValue& value, const TUnboxedValuePod& key) {
  130. Y_DEBUG_ABORT_UNLESS(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
  131. return value.Contains(key);
  132. }
  133. inline TUnboxedValue TBoxedValueAccessor::Lookup(const IBoxedValue& value, const TUnboxedValuePod& key) {
  134. Y_DEBUG_ABORT_UNLESS(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
  135. return value.Lookup(key);
  136. }
  137. inline TUnboxedValue TBoxedValueAccessor::GetElement(const IBoxedValue& value, ui32 index) {
  138. Y_DEBUG_ABORT_UNLESS(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
  139. return value.GetElement(index);
  140. }
  141. inline const TUnboxedValue* TBoxedValueAccessor::GetElements(const IBoxedValue& value) {
  142. Y_DEBUG_ABORT_UNLESS(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
  143. return value.GetElements();
  144. }
  145. inline TUnboxedValue TBoxedValueAccessor::Run(const IBoxedValue& value, const IValueBuilder* valueBuilder, const TUnboxedValuePod* args) {
  146. Y_DEBUG_ABORT_UNLESS(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
  147. return value.Run(valueBuilder, args);
  148. }
  149. inline TStringRef TBoxedValueAccessor::GetResourceTag(const IBoxedValue& value) {
  150. Y_DEBUG_ABORT_UNLESS(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
  151. return value.GetResourceTag();
  152. }
  153. inline void* TBoxedValueAccessor::GetResource(IBoxedValue& value) {
  154. Y_DEBUG_ABORT_UNLESS(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
  155. return value.GetResource();
  156. }
  157. inline bool TBoxedValueAccessor::HasListItems(const IBoxedValue& value) {
  158. Y_DEBUG_ABORT_UNLESS(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
  159. return value.HasListItems();
  160. }
  161. inline bool TBoxedValueAccessor::HasDictItems(const IBoxedValue& value) {
  162. Y_DEBUG_ABORT_UNLESS(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
  163. return value.HasDictItems();
  164. }
  165. inline ui32 TBoxedValueAccessor::GetVariantIndex(const IBoxedValue& value) {
  166. Y_DEBUG_ABORT_UNLESS(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
  167. return value.GetVariantIndex();
  168. }
  169. inline TUnboxedValue TBoxedValueAccessor::GetVariantItem(const IBoxedValue& value) {
  170. Y_DEBUG_ABORT_UNLESS(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
  171. return value.GetVariantItem();
  172. }
  173. inline EFetchStatus TBoxedValueAccessor::Fetch(IBoxedValue& value, TUnboxedValue& result) {
  174. Y_DEBUG_ABORT_UNLESS(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
  175. return value.Fetch(result);
  176. }
  177. inline bool TBoxedValueAccessor::Skip(IBoxedValue& value) {
  178. Y_DEBUG_ABORT_UNLESS(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
  179. return value.Skip();
  180. }
  181. inline bool TBoxedValueAccessor::Next(IBoxedValue& value, TUnboxedValue& result) {
  182. Y_DEBUG_ABORT_UNLESS(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
  183. return value.Next(result);
  184. }
  185. inline bool TBoxedValueAccessor::NextPair(IBoxedValue& value, TUnboxedValue& key, TUnboxedValue& payload) {
  186. Y_DEBUG_ABORT_UNLESS(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
  187. return value.NextPair(key, payload);
  188. }
  189. inline void TBoxedValueAccessor::Apply(IBoxedValue& value, IApplyContext& context) {
  190. Y_DEBUG_ABORT_UNLESS(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
  191. return value.Apply(context);
  192. }
  193. #if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 3)
  194. inline ui32 TBoxedValueAccessor::GetTraverseCount(const IBoxedValue& value) {
  195. Y_DEBUG_ABORT_UNLESS(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 3)));
  196. return value.GetTraverseCount();
  197. }
  198. inline TUnboxedValue TBoxedValueAccessor::GetTraverseItem(const IBoxedValue& value, ui32 index) {
  199. Y_DEBUG_ABORT_UNLESS(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 3)));
  200. return value.GetTraverseItem(index);
  201. }
  202. inline TUnboxedValue TBoxedValueAccessor::Save(const IBoxedValue& value) {
  203. Y_DEBUG_ABORT_UNLESS(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 3)));
  204. return value.Save();
  205. }
  206. inline void TBoxedValueAccessor::Load(IBoxedValue& value, const TStringRef& state) {
  207. Y_DEBUG_ABORT_UNLESS(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 3)));
  208. value.Load(state);
  209. }
  210. #endif
  211. #if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 11)
  212. inline void TBoxedValueAccessor::Push(IBoxedValue& value, const TUnboxedValuePod& data) {
  213. Y_DEBUG_ABORT_UNLESS(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 11)));
  214. return value.Push(data);
  215. }
  216. #endif
  217. #if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 12)
  218. inline bool TBoxedValueAccessor::IsSortedDict(IBoxedValue& value) {
  219. if (!value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 12))) {
  220. return false;
  221. }
  222. return value.IsSortedDict();
  223. }
  224. #endif
  225. #if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 30)
  226. inline EFetchStatus TBoxedValueAccessor::WideFetch(IBoxedValue& value, TUnboxedValue* result, ui32 width) {
  227. Y_DEBUG_ABORT_UNLESS(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 30)));
  228. return value.WideFetch(result, width);
  229. }
  230. #endif
  231. #if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 36)
  232. inline bool TBoxedValueAccessor::Load2(IBoxedValue& value, const TUnboxedValue& data) {
  233. if (!value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 36))) {
  234. return false;
  235. }
  236. return value.Load2(data);
  237. }
  238. #endif
  239. //////////////////////////////////////////////////////////////////////////////
  240. // TUnboxedValue
  241. //////////////////////////////////////////////////////////////////////////////
  242. Y_FORCE_INLINE TUnboxedValue::TUnboxedValue(const TUnboxedValuePod& value) noexcept
  243. : TUnboxedValuePod(value)
  244. {
  245. Ref();
  246. }
  247. Y_FORCE_INLINE TUnboxedValue::TUnboxedValue(TUnboxedValuePod&& value) noexcept
  248. : TUnboxedValuePod(std::move(value))
  249. {
  250. value.Raw = TRaw();
  251. Ref();
  252. }
  253. Y_FORCE_INLINE TUnboxedValue::TUnboxedValue(const TUnboxedValue& value) noexcept
  254. : TUnboxedValuePod(static_cast<const TUnboxedValuePod&>(value))
  255. {
  256. Ref();
  257. }
  258. Y_FORCE_INLINE TUnboxedValue::TUnboxedValue(TUnboxedValue&& value) noexcept
  259. : TUnboxedValuePod(static_cast<TUnboxedValuePod&&>(value))
  260. {
  261. value.Raw = TRaw();
  262. }
  263. Y_FORCE_INLINE TUnboxedValue& TUnboxedValue::operator=(const TUnboxedValue& value) noexcept
  264. {
  265. if (this != &value) {
  266. value.Ref();
  267. UnRef();
  268. Raw = value.Raw;
  269. }
  270. return *this;
  271. }
  272. Y_FORCE_INLINE TUnboxedValue& TUnboxedValue::operator=(TUnboxedValue&& value) noexcept
  273. {
  274. if (this != &value) {
  275. UnRef();
  276. Raw = value.Raw;
  277. value.Raw = TRaw();
  278. }
  279. return *this;
  280. }
  281. Y_FORCE_INLINE TUnboxedValuePod TUnboxedValue::Release() noexcept {
  282. const TUnboxedValuePod value(std::move(*static_cast<TUnboxedValuePod*>(this)));
  283. Raw = TRaw();
  284. value.ReleaseRef();
  285. return value;
  286. }
  287. Y_FORCE_INLINE void TUnboxedValue::Clear() noexcept
  288. {
  289. UnRef();
  290. Raw = TRaw();
  291. }
  292. Y_FORCE_INLINE TUnboxedValue::~TUnboxedValue() noexcept
  293. {
  294. UnRef();
  295. }
  296. //////////////////////////////////////////////////////////////////////////////
  297. // TUnboxedValuePod
  298. //////////////////////////////////////////////////////////////////////////////
  299. Y_FORCE_INLINE TUnboxedValuePod::TUnboxedValuePod(IBoxedValuePtr&& value)
  300. {
  301. Raw.Boxed.Meta = static_cast<ui8>(EMarkers::Boxed);
  302. Raw.Boxed.Value = value.Release();
  303. Raw.Boxed.Value->ReleaseRef();
  304. }
  305. Y_FORCE_INLINE TUnboxedValuePod::TUnboxedValuePod(TStringValue&& value, ui32 size, ui32 offset)
  306. {
  307. Y_DEBUG_ABORT_UNLESS(size);
  308. Y_DEBUG_ABORT_UNLESS(offset < std::min(OffsetLimit, value.Size()));
  309. Raw.String.Size = std::min(value.Size() - offset, size);
  310. Raw.String.Offset = offset;
  311. Raw.String.Value = value.ReleaseBuf();
  312. Raw.String.Meta = static_cast<ui8>(EMarkers::String);
  313. }
  314. inline TStringValue TUnboxedValuePod::AsStringValue() const
  315. {
  316. UDF_VERIFY(IsString(), "Value is not a string");
  317. return TStringValue(Raw.String.Value);
  318. }
  319. inline IBoxedValuePtr TUnboxedValuePod::AsBoxed() const
  320. {
  321. UDF_VERIFY(IsBoxed(), "Value is not boxed");
  322. return IBoxedValuePtr(Raw.Boxed.Value);
  323. }
  324. inline TStringValue::TData* TUnboxedValuePod::AsRawStringValue() const
  325. {
  326. UDF_VERIFY(IsString(), "Value is not a string");
  327. return Raw.String.Value;
  328. }
  329. inline IBoxedValue* TUnboxedValuePod::AsRawBoxed() const
  330. {
  331. UDF_VERIFY(IsBoxed(), "Value is not boxed");
  332. return Raw.Boxed.Value;
  333. }
  334. inline bool TUnboxedValuePod::UniqueBoxed() const
  335. {
  336. UDF_VERIFY(IsBoxed(), "Value is not boxed");
  337. return Raw.Boxed.Value->RefCount() <= 1;
  338. }
  339. inline bool TUnboxedValuePod::HasFastListLength() const {
  340. UDF_VERIFY(IsBoxed(), "Value is not a list");
  341. return TBoxedValueAccessor::HasFastListLength(*Raw.Boxed.Value);
  342. }
  343. #if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 11)
  344. inline void TUnboxedValuePod::Push(const TUnboxedValuePod& value) const {
  345. UDF_VERIFY(IsBoxed(), "Value is not a list");
  346. return TBoxedValueAccessor::Push(*Raw.Boxed.Value, value);
  347. }
  348. #endif
  349. inline ui64 TUnboxedValuePod::GetListLength() const
  350. {
  351. UDF_VERIFY(IsBoxed(), "Value is not a list");
  352. return TBoxedValueAccessor::GetListLength(*Raw.Boxed.Value);
  353. }
  354. inline ui64 TUnboxedValuePod::GetEstimatedListLength() const {
  355. UDF_VERIFY(IsBoxed(), "Value is not a list");
  356. return TBoxedValueAccessor::GetEstimatedListLength(*Raw.Boxed.Value);
  357. }
  358. inline bool TUnboxedValuePod::HasListItems() const {
  359. UDF_VERIFY(IsBoxed(), "Value is not a list");
  360. return TBoxedValueAccessor::HasListItems(*Raw.Boxed.Value);
  361. }
  362. inline TUnboxedValue TUnboxedValuePod::GetListIterator() const
  363. {
  364. UDF_VERIFY(IsBoxed(), "Value is not a list");
  365. return TBoxedValueAccessor::GetListIterator(*Raw.Boxed.Value);
  366. }
  367. inline TUnboxedValuePod TUnboxedValuePod::MakeOptional() const
  368. {
  369. if (Raw.Simple.Meta)
  370. return *this;
  371. TUnboxedValuePod result(*this);
  372. ++result.Raw.Simple.Count;
  373. return result;
  374. }
  375. inline TUnboxedValuePod TUnboxedValuePod::GetOptionalValue() const
  376. {
  377. if (Raw.Simple.Meta)
  378. return *this;
  379. UDF_VERIFY(Raw.Simple.Count > 0U, "Can't get value from empty.");
  380. TUnboxedValuePod result(*this);
  381. --result.Raw.Simple.Count;
  382. return result;
  383. }
  384. template<> inline TUnboxedValuePod TUnboxedValuePod::GetOptionalValueIf<false>() const { return *this; }
  385. template<> inline TUnboxedValuePod TUnboxedValuePod::GetOptionalValueIf<true>() const { return GetOptionalValue(); }
  386. template<> inline TUnboxedValuePod TUnboxedValuePod::MakeOptionalIf<false>() const { return *this; }
  387. template<> inline TUnboxedValuePod TUnboxedValuePod::MakeOptionalIf<true>() const { return MakeOptional(); }
  388. inline ui64 TUnboxedValuePod::GetDictLength() const
  389. {
  390. UDF_VERIFY(IsBoxed(), "Value is not a dict");
  391. return TBoxedValueAccessor::GetDictLength(*Raw.Boxed.Value);
  392. }
  393. inline TUnboxedValue TUnboxedValuePod::GetDictIterator() const
  394. {
  395. UDF_VERIFY(IsBoxed(), "Value is not a dict");
  396. return TBoxedValueAccessor::GetDictIterator(*Raw.Boxed.Value);
  397. }
  398. inline TUnboxedValue TUnboxedValuePod::GetKeysIterator() const
  399. {
  400. UDF_VERIFY(IsBoxed(), "Value is not a dict");
  401. return TBoxedValueAccessor::GetKeysIterator(*Raw.Boxed.Value);
  402. }
  403. inline TUnboxedValue TUnboxedValuePod::GetPayloadsIterator() const
  404. {
  405. UDF_VERIFY(IsBoxed(), "Value is not a dict");
  406. return TBoxedValueAccessor::GetPayloadsIterator(*Raw.Boxed.Value);
  407. }
  408. inline bool TUnboxedValuePod::Contains(const TUnboxedValuePod& key) const
  409. {
  410. UDF_VERIFY(IsBoxed(), "Value is not a dict");
  411. return TBoxedValueAccessor::Contains(*Raw.Boxed.Value, key);
  412. }
  413. inline TUnboxedValue TUnboxedValuePod::Lookup(const TUnboxedValuePod& key) const
  414. {
  415. UDF_VERIFY(IsBoxed(), "Value is not a dict");
  416. return TBoxedValueAccessor::Lookup(*Raw.Boxed.Value, key);
  417. }
  418. inline bool TUnboxedValuePod::HasDictItems() const {
  419. UDF_VERIFY(IsBoxed(), "Value is not a dict");
  420. return TBoxedValueAccessor::HasDictItems(*Raw.Boxed.Value);
  421. }
  422. inline TUnboxedValue TUnboxedValuePod::GetElement(ui32 index) const
  423. {
  424. UDF_VERIFY(IsBoxed(), "Value is not a tuple");
  425. return TBoxedValueAccessor::GetElement(*Raw.Boxed.Value, index);
  426. }
  427. inline const TUnboxedValue* TUnboxedValuePod::GetElements() const
  428. {
  429. UDF_VERIFY(IsBoxed(), "Value is not a tuple");
  430. return TBoxedValueAccessor::GetElements(*Raw.Boxed.Value);
  431. }
  432. inline TUnboxedValue TUnboxedValuePod::Run(
  433. const IValueBuilder* valueBuilder, const TUnboxedValuePod* args) const
  434. {
  435. UDF_VERIFY(IsBoxed(), "Value is not a callable");
  436. return TBoxedValueAccessor::Run(*Raw.Boxed.Value, valueBuilder, args);
  437. }
  438. inline TStringRef TUnboxedValuePod::GetResourceTag() const {
  439. UDF_VERIFY(IsBoxed(), "Value is not a resource");
  440. return TBoxedValueAccessor::GetResourceTag(*Raw.Boxed.Value);
  441. }
  442. inline void* TUnboxedValuePod::GetResource() const {
  443. UDF_VERIFY(IsBoxed(), "Value is not a resource");
  444. return TBoxedValueAccessor::GetResource(*Raw.Boxed.Value);
  445. }
  446. inline ui32 TUnboxedValuePod::GetVariantIndex() const {
  447. if (auto index = Raw.GetIndex())
  448. return --index;
  449. UDF_VERIFY(IsBoxed(), "Value is not a variant");
  450. return TBoxedValueAccessor::GetVariantIndex(*Raw.Boxed.Value);
  451. }
  452. inline TUnboxedValue TUnboxedValuePod::GetVariantItem() const {
  453. if (Raw.GetIndex()) {
  454. TUnboxedValuePod item(*this);
  455. item.Raw.Simple.Meta &= 0x3;
  456. return std::move(item);
  457. }
  458. UDF_VERIFY(IsBoxed(), "Value is not a variant");
  459. return TBoxedValueAccessor::GetVariantItem(*Raw.Boxed.Value);
  460. }
  461. inline bool TUnboxedValuePod::TryMakeVariant(ui32 index) {
  462. static const ui32 limit = (1U << 6U) - 1U;
  463. if (index >= limit || Raw.GetIndex())
  464. return false;
  465. Raw.Simple.Meta |= ui8(++index << 2);
  466. return true;
  467. }
  468. inline void TUnboxedValuePod::SetTimezoneId(ui16 id) {
  469. UDF_VERIFY(IsEmbedded(), "Value is not a datetime");
  470. Raw.Simple.TimezoneId = id;
  471. }
  472. inline ui16 TUnboxedValuePod::GetTimezoneId() const {
  473. UDF_VERIFY(IsEmbedded(), "Value is not a datetime");
  474. return Raw.Simple.TimezoneId;
  475. }
  476. inline EFetchStatus TUnboxedValuePod::Fetch(TUnboxedValue& result) const {
  477. UDF_VERIFY(IsBoxed(), "Value is not a stream");
  478. return TBoxedValueAccessor::Fetch(*Raw.Boxed.Value, result);
  479. }
  480. inline bool TUnboxedValuePod::Skip() const {
  481. UDF_VERIFY(IsBoxed(), "Value is not a iterator");
  482. return TBoxedValueAccessor::Skip(*Raw.Boxed.Value);
  483. }
  484. inline bool TUnboxedValuePod::Next(TUnboxedValue& value) const {
  485. UDF_VERIFY(IsBoxed(), "Value is not a iterator");
  486. return TBoxedValueAccessor::Next(*Raw.Boxed.Value, value);
  487. }
  488. inline bool TUnboxedValuePod::NextPair(TUnboxedValue& key, TUnboxedValue& payload) const {
  489. UDF_VERIFY(IsBoxed(), "Value is not a iterator");
  490. return TBoxedValueAccessor::NextPair(*Raw.Boxed.Value, key, payload);
  491. }
  492. inline void TUnboxedValuePod::Apply(IApplyContext& context) const {
  493. UDF_VERIFY(IsBoxed(), "Value is not boxed");
  494. return TBoxedValueAccessor::Apply(*Raw.Boxed.Value, context);
  495. }
  496. #if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 3)
  497. inline ui32 TUnboxedValuePod::GetTraverseCount() const {
  498. UDF_VERIFY(IsBoxed(), "Value is not boxed");
  499. return TBoxedValueAccessor::GetTraverseCount(*Raw.Boxed.Value);
  500. }
  501. inline TUnboxedValue TUnboxedValuePod::GetTraverseItem(ui32 index) const {
  502. UDF_VERIFY(IsBoxed(), "Value is not boxed");
  503. return TBoxedValueAccessor::GetTraverseItem(*Raw.Boxed.Value, index);
  504. }
  505. inline TUnboxedValue TUnboxedValuePod::Save() const {
  506. UDF_VERIFY(IsBoxed(), "Value is not boxed");
  507. return TBoxedValueAccessor::Save(*Raw.Boxed.Value);
  508. }
  509. inline void TUnboxedValuePod::Load(const TStringRef& state) {
  510. UDF_VERIFY(IsBoxed(), "Value is not boxed");
  511. return TBoxedValueAccessor::Load(*Raw.Boxed.Value, state);
  512. }
  513. #endif
  514. #if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 12)
  515. inline bool TUnboxedValuePod::IsSortedDict() const {
  516. UDF_VERIFY(IsBoxed(), "Value is not boxed");
  517. return TBoxedValueAccessor::IsSortedDict(*Raw.Boxed.Value);
  518. }
  519. #endif
  520. #if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 30)
  521. inline EFetchStatus TUnboxedValuePod::WideFetch(TUnboxedValue* result, ui32 width) const {
  522. UDF_VERIFY(IsBoxed(), "Value is not a wide stream");
  523. return TBoxedValueAccessor::WideFetch(*Raw.Boxed.Value, result, width);
  524. }
  525. #endif
  526. #if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 36)
  527. inline bool TUnboxedValuePod::Load2(const TUnboxedValue& value) {
  528. UDF_VERIFY(IsBoxed(), "Value is not boxed");
  529. return TBoxedValueAccessor::Load2(*Raw.Boxed.Value, value);
  530. }
  531. #endif
  532. Y_FORCE_INLINE void TUnboxedValuePod::Ref() const noexcept
  533. {
  534. switch (Raw.GetMarkers()) {
  535. case EMarkers::String: return Raw.String.Value->Ref();
  536. case EMarkers::Boxed: return Raw.Boxed.Value->Ref();
  537. default: return;
  538. }
  539. }
  540. Y_FORCE_INLINE void TUnboxedValuePod::UnRef() const noexcept
  541. {
  542. switch (Raw.GetMarkers()) {
  543. case EMarkers::String: return Raw.String.Value->UnRef();
  544. case EMarkers::Boxed: return Raw.Boxed.Value->UnRef();
  545. default: return;
  546. }
  547. }
  548. Y_FORCE_INLINE void TUnboxedValuePod::ReleaseRef() const noexcept
  549. {
  550. switch (Raw.GetMarkers()) {
  551. case EMarkers::String: return Raw.String.Value->ReleaseRef();
  552. case EMarkers::Boxed: return Raw.Boxed.Value->ReleaseRef();
  553. default: return;
  554. }
  555. }
  556. Y_FORCE_INLINE void TUnboxedValuePod::DeleteUnreferenced() const noexcept
  557. {
  558. switch (Raw.GetMarkers()) {
  559. case EMarkers::String: return Raw.String.Value->DeleteUnreferenced();
  560. case EMarkers::Boxed: return Raw.Boxed.Value->DeleteUnreferenced();
  561. default: return;
  562. }
  563. }
  564. Y_FORCE_INLINE i32 TUnboxedValuePod::LockRef() const noexcept
  565. {
  566. switch (Raw.GetMarkers()) {
  567. case EMarkers::String: return Raw.String.Value->LockRef();
  568. case EMarkers::Boxed: return Raw.Boxed.Value->LockRef();
  569. default: return -1;
  570. }
  571. }
  572. Y_FORCE_INLINE void TUnboxedValuePod::UnlockRef(i32 prev) const noexcept
  573. {
  574. switch (Raw.GetMarkers()) {
  575. case EMarkers::String: return Raw.String.Value->UnlockRef(prev);
  576. case EMarkers::Boxed: return Raw.Boxed.Value->UnlockRef(prev);
  577. default: return;
  578. }
  579. }
  580. Y_FORCE_INLINE i32 TUnboxedValuePod::RefCount() const noexcept
  581. {
  582. switch (Raw.GetMarkers()) {
  583. case EMarkers::String: return Raw.String.Value->RefCount();
  584. case EMarkers::Boxed: return Raw.Boxed.Value->RefCount();
  585. default: return -1;
  586. }
  587. }
  588. #define VALUE_GET(xType) \
  589. template <> \
  590. inline xType TUnboxedValuePod::Get<xType>() const \
  591. { \
  592. UDF_VERIFY(EMarkers::Embedded == Raw.GetMarkers(), "Value is empty."); \
  593. return Raw.Simple.xType##_; \
  594. }
  595. #define VALUE_GET_DEF(xType) \
  596. template <> \
  597. inline xType TUnboxedValuePod::GetOrDefault<xType>(xType def) const \
  598. { \
  599. return EMarkers::Empty == Raw.GetMarkers() ? def : Raw.Simple.xType##_; \
  600. }
  601. #define VALUE_CONSTR(xType) \
  602. template <> \
  603. inline TUnboxedValuePod::TUnboxedValuePod(xType value) \
  604. { \
  605. Raw.Simple.xType##_ = value; \
  606. Raw.Simple.Meta = static_cast<ui8>(EMarkers::Embedded); \
  607. }
  608. PRIMITIVE_VALUE_TYPES(VALUE_GET)
  609. PRIMITIVE_VALUE_TYPES(VALUE_GET_DEF)
  610. PRIMITIVE_VALUE_TYPES(VALUE_CONSTR)
  611. #undef VALUE_GET
  612. #undef VALUE_GET_DEF
  613. #undef VALUE_CONSTR
  614. template <>
  615. inline bool TUnboxedValuePod::Get<bool>() const
  616. {
  617. UDF_VERIFY(EMarkers::Empty != Raw.GetMarkers(), "Value is empty.");
  618. return bool(Raw.Simple.ui8_);
  619. }
  620. template <>
  621. inline bool TUnboxedValuePod::GetOrDefault<bool>(bool def) const
  622. {
  623. return EMarkers::Empty == Raw.GetMarkers() ? def : bool(Raw.Simple.ui8_);
  624. }
  625. template <>
  626. inline NYql::NDecimal::TInt128 TUnboxedValuePod::Get<NYql::NDecimal::TInt128>() const
  627. {
  628. return GetInt128();
  629. }
  630. template <>
  631. inline TUnboxedValuePod::TUnboxedValuePod(bool value)
  632. {
  633. Raw.Simple.ui8_ = value ? 1 : 0;
  634. Raw.Simple.Meta = static_cast<ui8>(EMarkers::Embedded);
  635. }
  636. inline NYql::NDecimal::TInt128 TUnboxedValuePod::GetInt128() const
  637. {
  638. UDF_VERIFY(EMarkers::Empty != Raw.GetMarkers(), "Value is empty.");
  639. auto v = *reinterpret_cast<const NYql::NDecimal::TInt128*>(&Raw);
  640. const auto p = reinterpret_cast<ui8*>(&v);
  641. p[0xF] = (p[0xE] & 0x80) ? 0xFF : 0x00;
  642. return v;
  643. }
  644. inline NYql::NDecimal::TUint128 TUnboxedValuePod::GetUint128() const
  645. {
  646. UDF_VERIFY(EMarkers::Empty != Raw.GetMarkers(), "Value is empty.");
  647. auto v = *reinterpret_cast<const NYql::NDecimal::TUint128*>(&Raw);
  648. const auto p = reinterpret_cast<ui8*>(&v);
  649. p[0xF] = (p[0xE] & 0x80) ? 0xFF : 0x00;
  650. return v;
  651. }
  652. inline TUnboxedValuePod::TUnboxedValuePod(NYql::NDecimal::TInt128 value)
  653. {
  654. *reinterpret_cast<NYql::NDecimal::TInt128*>(&Raw) = value;
  655. Raw.Simple.Meta = static_cast<ui8>(EMarkers::Embedded);
  656. }
  657. inline TUnboxedValuePod::TUnboxedValuePod(NYql::NDecimal::TUint128 value)
  658. {
  659. *reinterpret_cast<NYql::NDecimal::TUint128*>(&Raw) = value;
  660. Raw.Simple.Meta = static_cast<ui8>(EMarkers::Embedded);
  661. }
  662. inline const void* TUnboxedValuePod::GetRawPtr() const
  663. {
  664. return &Raw;
  665. }
  666. inline void* TUnboxedValuePod::GetRawPtr()
  667. {
  668. return &Raw;
  669. }
  670. inline TUnboxedValuePod TUnboxedValuePod::Void()
  671. {
  672. TUnboxedValuePod v;
  673. v.Raw.Simple.Meta = static_cast<ui8>(EMarkers::Embedded);
  674. return v;
  675. }
  676. inline TUnboxedValuePod TUnboxedValuePod::Zero()
  677. {
  678. TUnboxedValuePod v;
  679. v.Raw.Simple.Meta = static_cast<ui8>(EMarkers::Embedded);
  680. return v;
  681. }
  682. inline TUnboxedValuePod TUnboxedValuePod::Embedded(ui8 size) {
  683. UDF_VERIFY(size <= InternalBufferSize);
  684. TUnboxedValuePod v;
  685. v.Raw.Embedded.Size = size;
  686. v.Raw.Embedded.Meta = static_cast<ui8>(EMarkers::Embedded);
  687. return v;
  688. }
  689. inline TUnboxedValuePod TUnboxedValuePod::Embedded(const TStringRef& value) {
  690. UDF_VERIFY(value.Size() <= InternalBufferSize);
  691. TUnboxedValuePod v;
  692. v.Raw.Embedded.Size = value.Size();
  693. v.Raw.Embedded.Meta = static_cast<ui8>(EMarkers::Embedded);
  694. if (v.Raw.Embedded.Size) {
  695. std::memcpy(v.Raw.Embedded.Buffer, value.Data(), v.Raw.Embedded.Size);
  696. }
  697. return v;
  698. }
  699. inline TUnboxedValuePod TUnboxedValuePod::Invalid()
  700. {
  701. TUnboxedValuePod v;
  702. v.Raw.Simple.Count = std::numeric_limits<ui64>::max();
  703. return v;
  704. }
  705. inline TUnboxedValuePod TUnboxedValuePod::MakeFinish()
  706. {
  707. TUnboxedValuePod v;
  708. v.Raw.Simple.Count = std::numeric_limits<ui64>::max() - 1U;
  709. return v;
  710. }
  711. inline TUnboxedValuePod TUnboxedValuePod::MakeYield()
  712. {
  713. return Invalid();
  714. }
  715. inline bool TUnboxedValuePod::IsInvalid() const
  716. {
  717. return Raw.Simple.Count == std::numeric_limits<ui64>::max() && Raw.Simple.FullMeta == 0;
  718. }
  719. inline bool TUnboxedValuePod::IsFinish() const
  720. {
  721. return Raw.Simple.Count == std::numeric_limits<ui64>::max() - 1U && Raw.Simple.FullMeta == 0;
  722. }
  723. inline bool TUnboxedValuePod::IsYield() const
  724. {
  725. return IsInvalid();
  726. }
  727. inline bool TUnboxedValuePod::IsSpecial() const
  728. {
  729. return Raw.Simple.FullMeta == 0 && Raw.Simple.Count >= std::numeric_limits<ui64>::max() - 1U;
  730. }
  731. inline TStringRef TUnboxedValuePod::AsStringRef() const&
  732. {
  733. switch (Raw.GetMarkers()) {
  734. case EMarkers::Embedded: return { Raw.Embedded.Buffer, Raw.Embedded.Size };
  735. case EMarkers::String: return { Raw.String.Value->Data() + (Raw.String.Offset & 0xFFFFFF), Raw.String.Size };
  736. default: Y_ABORT("Value is not a string.");
  737. }
  738. }
  739. inline TMutableStringRef TUnboxedValuePod::AsStringRef() &
  740. {
  741. switch (Raw.GetMarkers()) {
  742. case EMarkers::Embedded: return { Raw.Embedded.Buffer, Raw.Embedded.Size };
  743. case EMarkers::String: return { Raw.String.Value->Data() + (Raw.String.Offset & 0xFFFFFF), Raw.String.Size };
  744. default: Y_ABORT("Value is not a string.");
  745. }
  746. }