scimpl.h 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858
  1. #pragma once
  2. #include "scheme.h"
  3. #include <util/stream/output.h>
  4. namespace NSc {
  5. struct TValue::TScCore : TAtomicRefCount<TScCore, TDestructor>, TNonCopyable {
  6. TPoolPtr Pool;
  7. double FloatNumber = 0;
  8. i64 IntNumber = 0;
  9. TStringBuf String;
  10. TDict Dict;
  11. TArray Array;
  12. TValue::EType ValueType = TValue::EType::Null;
  13. TScCore(TPoolPtr& p)
  14. : Pool(p)
  15. , Dict(Pool->Get())
  16. , Array(Pool->Get())
  17. {
  18. }
  19. bool IsNull() const {
  20. return TValue::EType::Null == ValueType;
  21. }
  22. bool IsBool() const {
  23. return TValue::EType::Bool == ValueType;
  24. }
  25. bool IsIntNumber() const {
  26. return TValue::EType::IntNumber == ValueType || IsBool();
  27. }
  28. bool IsNumber() const {
  29. return TValue::EType::FloatNumber == ValueType || IsIntNumber();
  30. }
  31. bool IsString() const {
  32. return TValue::EType::String == ValueType;
  33. }
  34. bool IsArray() const {
  35. return TValue::EType::Array == ValueType;
  36. }
  37. bool IsDict() const {
  38. return TValue::EType::Dict == ValueType;
  39. }
  40. bool HasChildren() const {
  41. return GetDict().size() + GetArray().size();
  42. }
  43. void SetNull() {
  44. ValueType = TValue::EType::Null;
  45. }
  46. void SetArray() {
  47. if (Y_LIKELY(IsArray())) {
  48. return;
  49. }
  50. ValueType = TValue::EType::Array;
  51. Array.clear();
  52. }
  53. void SetDict() {
  54. if (Y_LIKELY(IsDict())) {
  55. return;
  56. }
  57. ValueType = TValue::EType::Dict;
  58. Dict.clear();
  59. }
  60. void SetNumber(double n) {
  61. ValueType = TValue::EType::FloatNumber;
  62. FloatNumber = n;
  63. }
  64. void SetIntNumber(i64 n) {
  65. ValueType = TValue::EType::IntNumber;
  66. IntNumber = n;
  67. }
  68. void SetBool(bool b) {
  69. ValueType = TValue::EType::Bool;
  70. IntNumber = b;
  71. }
  72. void SetString(TStringBuf s) {
  73. SetOwnedString(Pool->AppendBuf(s));
  74. }
  75. void SetOwnedString(TStringBuf s) {
  76. ValueType = TValue::EType::String;
  77. String = s;
  78. }
  79. double& GetNumberMutable(double defaultnum) {
  80. switch (ValueType) {
  81. case TValue::EType::Bool:
  82. SetNumber(bool(IntNumber));
  83. break;
  84. case TValue::EType::IntNumber:
  85. SetNumber(IntNumber);
  86. break;
  87. case TValue::EType::FloatNumber:
  88. break;
  89. default:
  90. SetNumber(defaultnum);
  91. break;
  92. }
  93. return FloatNumber;
  94. }
  95. i64& GetIntNumberMutable(i64 defaultnum) {
  96. switch (ValueType) {
  97. case TValue::EType::Bool:
  98. SetIntNumber(bool(IntNumber));
  99. break;
  100. case TValue::EType::IntNumber:
  101. break;
  102. case TValue::EType::FloatNumber:
  103. SetIntNumber(FloatNumber);
  104. break;
  105. default:
  106. SetIntNumber(defaultnum);
  107. break;
  108. }
  109. return IntNumber;
  110. }
  111. void ClearArray() {
  112. if (!IsArray()) {
  113. return;
  114. }
  115. Array.clear();
  116. }
  117. void ClearDict() {
  118. if (!IsDict()) {
  119. return;
  120. }
  121. Dict.clear();
  122. }
  123. double GetNumber(double d = 0) const {
  124. switch (ValueType) {
  125. case TValue::EType::Bool:
  126. return (bool)IntNumber;
  127. case TValue::EType::IntNumber:
  128. return IntNumber;
  129. case TValue::EType::FloatNumber:
  130. return FloatNumber;
  131. default:
  132. return d;
  133. }
  134. }
  135. i64 GetIntNumber(i64 n = 0) const {
  136. switch (ValueType) {
  137. case TValue::EType::Bool:
  138. return (bool)IntNumber;
  139. case TValue::EType::IntNumber:
  140. return IntNumber;
  141. case TValue::EType::FloatNumber:
  142. return FloatNumber;
  143. default:
  144. return n;
  145. }
  146. }
  147. bool GetBool(bool b = false) const {
  148. return GetIntNumber(b);
  149. }
  150. TStringBuf GetString(TStringBuf s = TStringBuf()) const {
  151. return IsString() ? String : s;
  152. }
  153. const TArray& GetArray() const {
  154. return IsArray() ? Array : TValue::DefaultArray();
  155. }
  156. TArray& GetArrayMutable() {
  157. SetArray();
  158. return Array;
  159. }
  160. TDict& GetDictMutable() {
  161. SetDict();
  162. return Dict;
  163. }
  164. const TDict& GetDict() const {
  165. return IsDict() ? Dict : TValue::DefaultDict();
  166. }
  167. static void DoPush(TPoolPtr& p, TArray& a) {
  168. a.push_back(TValue(p));
  169. a.back().CopyOnWrite = false;
  170. }
  171. TValue& Push() {
  172. SetArray();
  173. DoPush(Pool, Array);
  174. return Array.back();
  175. }
  176. TValue Pop() {
  177. if (!IsArray() || Array.empty()) {
  178. return TValue::DefaultValue();
  179. }
  180. TValue v = Array.back();
  181. Array.pop_back();
  182. return v;
  183. }
  184. const TValue& Get(size_t key) const {
  185. return IsArray() && Array.size() > key ? Array[key] : TValue::DefaultValue();
  186. }
  187. TValue* GetNoAdd(size_t key) {
  188. return IsArray() && Array.size() > key ? &Array[key] : nullptr;
  189. }
  190. TValue& GetOrAdd(size_t key) {
  191. SetArray();
  192. for (size_t i = Array.size(); i <= key; ++i) {
  193. DoPush(Pool, Array);
  194. }
  195. return Array[key];
  196. }
  197. TValue& Back() {
  198. SetArray();
  199. if (Array.empty()) {
  200. DoPush(Pool, Array);
  201. }
  202. return Array.back();
  203. }
  204. TValue& Insert(size_t key) {
  205. SetArray();
  206. if (Array.size() <= key) {
  207. return GetOrAdd(key);
  208. } else {
  209. Array.insert(Array.begin() + key, TValue(Pool));
  210. Array[key].CopyOnWrite = false;
  211. return Array[key];
  212. }
  213. }
  214. TValue Delete(size_t key) {
  215. if (!IsArray() || Array.size() <= key) {
  216. return TValue::DefaultValue();
  217. }
  218. TValue v = Array[key];
  219. Array.erase(Array.begin() + key);
  220. return v;
  221. }
  222. const TValue& Get(TStringBuf key) const {
  223. if (!IsDict()) {
  224. return TValue::DefaultValue();
  225. }
  226. TDict::const_iterator it = Dict.find(key);
  227. return it != Dict.end() ? it->second : TValue::DefaultValue();
  228. }
  229. TValue* GetNoAdd(TStringBuf key) {
  230. if (!IsDict()) {
  231. return nullptr;
  232. }
  233. return Dict.FindPtr(key);
  234. }
  235. TValue& Add(TStringBuf key) {
  236. SetDict();
  237. TDict::iterator it = Dict.insert(std::make_pair(Pool->AppendBuf(key), TValue(Pool))).first;
  238. it->second.CopyOnWrite = false;
  239. return it->second;
  240. }
  241. TValue& GetOrAdd(TStringBuf key) {
  242. SetDict();
  243. TDict::insert_ctx ctx;
  244. TDict::iterator it = Dict.find(key, ctx);
  245. if (it == Dict.end()) {
  246. it = Dict.insert_direct(std::make_pair(Pool->AppendBuf(key), TValue(Pool)), ctx);
  247. it->second.CopyOnWrite = false;
  248. }
  249. return it->second;
  250. }
  251. TValue Delete(TStringBuf key) {
  252. if (!IsDict()) {
  253. return TValue::DefaultValue();
  254. }
  255. TDict::iterator it = Dict.find(key);
  256. if (it == Dict.end()) {
  257. return TValue::DefaultValue();
  258. }
  259. TValue v = it->second;
  260. Dict.erase(key);
  261. return v;
  262. }
  263. };
  264. TValue::TScCore* TValue::NewCore(TPoolPtr& p) {
  265. return new (p->Pool.Allocate<TScCore>()) TScCore(p);
  266. }
  267. TValue::TValue() {
  268. auto p = TPoolPtr(new NDefinitions::TPool);
  269. TheCore = NewCore(p);
  270. }
  271. TValue::TValue(double t)
  272. : TValue()
  273. {
  274. SetNumber(t);
  275. }
  276. TValue::TValue(unsigned long long t)
  277. : TValue()
  278. {
  279. SetIntNumber(t);
  280. }
  281. TValue::TValue(unsigned long t)
  282. : TValue()
  283. {
  284. SetIntNumber(t);
  285. }
  286. TValue::TValue(unsigned t)
  287. : TValue()
  288. {
  289. SetIntNumber(t);
  290. }
  291. TValue::TValue(long long t)
  292. : TValue()
  293. {
  294. SetIntNumber(t);
  295. }
  296. TValue::TValue(long t)
  297. : TValue()
  298. {
  299. SetIntNumber(t);
  300. }
  301. TValue::TValue(int t)
  302. : TValue()
  303. {
  304. SetIntNumber(t);
  305. }
  306. //TValue::TValue(bool t)
  307. // : TValue()
  308. //{
  309. // SetBool(t);
  310. //}
  311. TValue::TValue(TStringBuf t)
  312. : TValue()
  313. {
  314. SetString(t);
  315. }
  316. TValue::TValue(const char* t)
  317. : TValue()
  318. {
  319. SetString(t);
  320. }
  321. TValue::TValue(TValue& v)
  322. : TheCore(v.TheCore)
  323. , CopyOnWrite(v.CopyOnWrite)
  324. {
  325. }
  326. TValue::TValue(const TValue& v)
  327. : TheCore(v.TheCore)
  328. , CopyOnWrite(true)
  329. {
  330. }
  331. TValue::TValue(TValue&& v) noexcept
  332. : TheCore(std::move(v.TheCore))
  333. , CopyOnWrite(v.CopyOnWrite)
  334. {}
  335. TValue::operator double() const {
  336. return GetNumber();
  337. }
  338. TValue::operator float() const {
  339. return GetNumber();
  340. }
  341. TValue::operator long long() const {
  342. return GetIntNumber();
  343. }
  344. TValue::operator long() const {
  345. return GetIntNumber();
  346. }
  347. TValue::operator int() const {
  348. return GetIntNumber();
  349. }
  350. TValue::operator short() const {
  351. return GetIntNumber();
  352. }
  353. TValue::operator char() const {
  354. return GetIntNumber();
  355. }
  356. TValue::operator unsigned long long() const {
  357. return GetIntNumber();
  358. }
  359. TValue::operator unsigned long() const {
  360. return GetIntNumber();
  361. }
  362. TValue::operator unsigned() const {
  363. return GetIntNumber();
  364. }
  365. TValue::operator unsigned short() const {
  366. return GetIntNumber();
  367. }
  368. TValue::operator unsigned char() const {
  369. return GetIntNumber();
  370. }
  371. TValue::operator signed char() const {
  372. return GetIntNumber();
  373. }
  374. TValue::operator TStringBuf() const {
  375. return GetString();
  376. }
  377. TValue::operator const ::NSc::TArray&() const {
  378. return GetArray();
  379. }
  380. TValue::operator const ::NSc::TDict&() const {
  381. return GetDict();
  382. }
  383. TValue& TValue::operator=(double t) {
  384. return SetNumber(t);
  385. }
  386. TValue& TValue::operator=(unsigned long long t) {
  387. return SetIntNumber(t);
  388. }
  389. TValue& TValue::operator=(unsigned long t) {
  390. return SetIntNumber(t);
  391. }
  392. TValue& TValue::operator=(unsigned t) {
  393. return SetIntNumber(t);
  394. }
  395. TValue& TValue::operator=(long long t) {
  396. return SetIntNumber(t);
  397. }
  398. TValue& TValue::operator=(long t) {
  399. return SetIntNumber(t);
  400. }
  401. TValue& TValue::operator=(int t) {
  402. return SetIntNumber(t);
  403. }
  404. //TValue& TValue::operator=(bool t) {
  405. // return SetBool(t);
  406. //}
  407. TValue& TValue::operator=(TStringBuf t) {
  408. return SetString(t);
  409. }
  410. TValue& TValue::operator=(const char* t) {
  411. return SetString(t);
  412. }
  413. TValue& TValue::operator=(TValue& v) & {
  414. if (!Same(*this, v)) {
  415. //Extend TheCore lifetime not to trigger possible v deletion via parent-child chain
  416. auto tmpCore = TheCore;
  417. TheCore = v.TheCore;
  418. CopyOnWrite = v.CopyOnWrite;
  419. }
  420. return *this;
  421. }
  422. TValue& TValue::operator=(const TValue& v) & {
  423. if (!Same(*this, v)) {
  424. //Extend TheCore lifetime not to trigger possible v deletion via parent-child chain
  425. auto tmpCore = TheCore;
  426. TheCore = v.TheCore;
  427. CopyOnWrite = true;
  428. }
  429. return *this;
  430. }
  431. TValue& TValue::operator=(TValue&& v) & noexcept {
  432. if (!Same(*this, v)) {
  433. //Extend TheCore lifetime not to trigger possible v deletion via parent-child chain
  434. auto tmpCore = TheCore;
  435. TheCore = std::move(v.TheCore);
  436. CopyOnWrite = v.CopyOnWrite;
  437. }
  438. return *this;
  439. }
  440. bool TValue::Has(size_t idx) const {
  441. return IsArray() && GetArray().size() > idx;
  442. }
  443. bool TValue::Has(TStringBuf s) const {
  444. return GetDict().contains(s);
  445. }
  446. TValue& TValue::GetOrAddUnsafe(size_t idx) {
  447. return CoreMutable().GetOrAdd(idx);
  448. }
  449. TValue& TValue::GetOrAdd(TStringBuf idx) {
  450. return CoreMutable().GetOrAdd(idx);
  451. }
  452. const TValue& TValue::Get(size_t idx) const {
  453. return Core().Get(idx);
  454. }
  455. TValue* TValue::GetNoAdd(size_t idx) {
  456. return CoreMutable().GetNoAdd(idx);
  457. }
  458. const TValue& TValue::Get(TStringBuf idx) const {
  459. return Core().Get(idx);
  460. }
  461. TValue* TValue::GetNoAdd(TStringBuf key) {
  462. return CoreMutable().GetNoAdd(key);
  463. }
  464. TValue& TValue::Back() {
  465. return CoreMutable().Back();
  466. }
  467. const TValue& TValue::Back() const {
  468. const TArray& arr = GetArray();
  469. return arr.empty() ? DefaultValue() : arr.back();
  470. }
  471. TValue TValue::Delete(size_t idx) {
  472. return CoreMutable().Delete(idx);
  473. }
  474. TValue TValue::Delete(TStringBuf idx) {
  475. return CoreMutable().Delete(idx);
  476. }
  477. TValue& TValue::AddAll(std::initializer_list<std::pair<TStringBuf, TValue>> t) {
  478. for (const auto& el : t) {
  479. Add(el.first) = el.second;
  480. }
  481. return *this;
  482. }
  483. TValue& TValue::InsertUnsafe(size_t idx) {
  484. return CoreMutable().Insert(idx);
  485. }
  486. template <class TIt>
  487. TValue& TValue::AppendAll(TIt begin, TIt end) {
  488. GetArrayMutable().AppendAll(begin, end);
  489. return *this;
  490. }
  491. template <class TColl>
  492. TValue& TValue::AppendAll(TColl&& coll) {
  493. return AppendAll(std::begin(coll), std::end(coll));
  494. }
  495. TValue& TValue::AppendAll(std::initializer_list<TValue> coll) {
  496. return AppendAll(coll.begin(), coll.end());
  497. }
  498. TValue& TValue::Push() {
  499. return CoreMutable().Push();
  500. }
  501. TValue TValue::Pop() {
  502. return CoreMutable().Pop();
  503. }
  504. TValue::EType TValue::GetType() const {
  505. return Core().ValueType;
  506. }
  507. bool TValue::IsNull() const {
  508. return Core().IsNull();
  509. }
  510. bool TValue::IsNumber() const {
  511. return Core().IsNumber();
  512. }
  513. bool TValue::IsIntNumber() const {
  514. return Core().IsIntNumber();
  515. }
  516. bool TValue::IsBool() const {
  517. return Core().IsBool();
  518. }
  519. bool TValue::IsString() const {
  520. return Core().IsString();
  521. }
  522. bool TValue::IsArray() const {
  523. return Core().IsArray();
  524. }
  525. bool TValue::IsDict() const {
  526. return Core().IsDict();
  527. }
  528. TValue& TValue::SetNumber(double i) {
  529. CoreMutableForSet().SetNumber(i);
  530. return *this;
  531. }
  532. TValue& TValue::SetIntNumber(i64 n) {
  533. CoreMutableForSet().SetIntNumber(n);
  534. return *this;
  535. }
  536. TValue& TValue::SetBool(bool val) {
  537. CoreMutableForSet().SetBool(val);
  538. return *this;
  539. }
  540. TValue& TValue::SetString(TStringBuf s) {
  541. CoreMutableForSet().SetString(s);
  542. return *this;
  543. }
  544. double TValue::GetNumber(double d) const {
  545. return Core().GetNumber(d);
  546. }
  547. i64 TValue::GetIntNumber(i64 n) const {
  548. return Core().GetIntNumber(n);
  549. }
  550. bool TValue::GetBool(bool b) const {
  551. return Core().GetBool(b);
  552. }
  553. double& TValue::GetNumberMutable(double defaultval) {
  554. return CoreMutable().GetNumberMutable(defaultval);
  555. }
  556. i64& TValue::GetIntNumberMutable(i64 defaultval) {
  557. return CoreMutable().GetIntNumberMutable(defaultval);
  558. }
  559. TStringBuf TValue::GetString(TStringBuf d) const {
  560. return Core().GetString(d);
  561. }
  562. TValue& TValue::SetArray() {
  563. CoreMutable().SetArray();
  564. return *this;
  565. }
  566. TValue& TValue::ClearArray() {
  567. CoreMutable().ClearArray();
  568. return *this;
  569. }
  570. TValue& TValue::SetDict() {
  571. CoreMutable().SetDict();
  572. return *this;
  573. }
  574. TValue& TValue::ClearDict() {
  575. CoreMutable().ClearDict();
  576. return *this;
  577. }
  578. const TArray& TValue::GetArray() const {
  579. return Core().GetArray();
  580. }
  581. TArray& TValue::GetArrayMutable() {
  582. return CoreMutable().GetArrayMutable();
  583. }
  584. const TDict& TValue::GetDict() const {
  585. return Core().GetDict();
  586. }
  587. TDict& TValue::GetDictMutable() {
  588. return CoreMutable().GetDictMutable();
  589. }
  590. size_t TValue::StringSize() const {
  591. return GetString().size();
  592. }
  593. size_t TValue::ArraySize() const {
  594. return GetArray().size();
  595. }
  596. size_t TValue::DictSize() const {
  597. return GetDict().size();
  598. }
  599. bool TValue::StringEmpty() const {
  600. return GetString().empty();
  601. }
  602. bool TValue::ArrayEmpty() const {
  603. return GetArray().empty();
  604. }
  605. bool TValue::DictEmpty() const {
  606. return GetDict().empty();
  607. }
  608. TValue::TValue(TPoolPtr& p)
  609. : TheCore(NewCore(p))
  610. {
  611. }
  612. TValue::TScCore& TValue::CoreMutable() {
  613. if (Y_UNLIKELY(!TheCore)) {
  614. *this = TValue();
  615. } else if (Y_UNLIKELY(CopyOnWrite) && Y_UNLIKELY(TheCore->RefCount() > 1)) {
  616. *this = Clone();
  617. }
  618. CopyOnWrite = false;
  619. return *TheCore;
  620. }
  621. TValue::TScCore& TValue::CoreMutableForSet() {
  622. if (Y_UNLIKELY(!TheCore) || Y_UNLIKELY(CopyOnWrite) && Y_UNLIKELY(TheCore->RefCount() > 1)) {
  623. *this = TValue();
  624. }
  625. CopyOnWrite = false;
  626. return *TheCore;
  627. }
  628. const TValue::TScCore& TValue::Core() const {
  629. return TheCore ? *TheCore : DefaultCore();
  630. }
  631. TValue& TValue::SetNull() {
  632. CoreMutableForSet().SetNull();
  633. return *this;
  634. }
  635. namespace NPrivate {
  636. int CompareStr(const NSc::TValue& a, TStringBuf b);
  637. int CompareInt(const NSc::TValue& a, i64 r);
  638. int CompareFloat(const NSc::TValue& a, double r);
  639. }
  640. bool operator==(const TValue& a, const TValue& b);
  641. bool operator!=(const TValue& a, const TValue& b);
  642. bool operator<=(const TValue&, const TValue&) = delete;
  643. bool operator>=(const TValue&, const TValue&) = delete;
  644. bool operator<(const TValue&, const TValue&) = delete;
  645. bool operator>(const TValue&, const TValue&) = delete;
  646. #define LIBRARY_SCHEME_DECLARE_TVALUE_OPS(T, Impl) \
  647. bool operator==(const NSc::TValue& a, T b); \
  648. bool operator==(T b, const NSc::TValue& a); \
  649. bool operator!=(const NSc::TValue& a, T b); \
  650. bool operator!=(T b, const NSc::TValue& a); \
  651. bool operator<=(const NSc::TValue& a, T b); \
  652. bool operator<=(T b, const NSc::TValue& a); \
  653. bool operator>=(const NSc::TValue& a, T b); \
  654. bool operator>=(T b, const NSc::TValue& a); \
  655. bool operator<(const NSc::TValue& a, T b); \
  656. bool operator<(T b, const NSc::TValue& a); \
  657. bool operator>(const NSc::TValue& a, T b); \
  658. bool operator>(T b, const NSc::TValue& a);
  659. #define LIBRARY_SCHEME_DECLARE_TVALUE_INT_OPS(T) \
  660. LIBRARY_SCHEME_DECLARE_TVALUE_OPS(signed T, CompareInt) \
  661. LIBRARY_SCHEME_DECLARE_TVALUE_OPS(unsigned T, CompareInt)
  662. //LIBRARY_SCHEME_DECLARE_TVALUE_OPS(bool, CompareInt)
  663. LIBRARY_SCHEME_DECLARE_TVALUE_OPS(char, CompareInt)
  664. LIBRARY_SCHEME_DECLARE_TVALUE_INT_OPS(char)
  665. LIBRARY_SCHEME_DECLARE_TVALUE_INT_OPS(short)
  666. LIBRARY_SCHEME_DECLARE_TVALUE_INT_OPS(int)
  667. LIBRARY_SCHEME_DECLARE_TVALUE_INT_OPS(long)
  668. LIBRARY_SCHEME_DECLARE_TVALUE_INT_OPS(long long)
  669. LIBRARY_SCHEME_DECLARE_TVALUE_OPS(float, CompareFloat)
  670. LIBRARY_SCHEME_DECLARE_TVALUE_OPS(double, CompareFloat)
  671. LIBRARY_SCHEME_DECLARE_TVALUE_OPS(TStringBuf, CompareStr)
  672. LIBRARY_SCHEME_DECLARE_TVALUE_OPS(const TString&, CompareStr)
  673. LIBRARY_SCHEME_DECLARE_TVALUE_OPS(const char* const, CompareStr)
  674. #undef LIBRARY_SCHEME_DECLARE_TVALUE_OPS
  675. #undef LIBRARY_SCHEME_DECLARE_TVALUE_INT_OPS
  676. }