scimpl_private.h 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. #pragma once
  2. #include "scheme.h"
  3. #include <util/thread/singleton.h>
  4. namespace NSc {
  5. namespace NImpl {
  6. template <typename TContext>
  7. static inline TContext& GetTlsInstance() {
  8. return *FastTlsSingleton<TContext>();
  9. }
  10. template <typename TContext>
  11. class TContextGuard : TNonCopyable {
  12. using TElement = typename TContext::TElement;
  13. using TTarget = typename TContext::TTarget;
  14. using TVectorType = TVector<TElement>;
  15. public:
  16. TContextGuard(TContext& ctx, TTarget& target)
  17. : Ctx(ctx)
  18. , Active(TContext::Needed(target))
  19. {
  20. if (Active) {
  21. Begin = Ctx.Vector.size();
  22. Ok = Ctx.Process(target);
  23. End = Ctx.Vector.size();
  24. }
  25. }
  26. ~TContextGuard() noexcept {
  27. if (Active) {
  28. Ctx.Vector.resize(Begin);
  29. }
  30. }
  31. const TVectorType& GetVector() const {
  32. return Ctx.Vector;
  33. }
  34. using const_iterator = size_t;
  35. size_t begin() const {
  36. return Begin;
  37. }
  38. size_t end() const {
  39. return End;
  40. }
  41. bool Ok = true;
  42. private:
  43. TContext& Ctx;
  44. size_t Begin = 0;
  45. size_t End = 0;
  46. bool Active = false;
  47. };
  48. template <typename TElem, typename TTgt>
  49. class TBasicContext {
  50. public:
  51. using TElement = TElem;
  52. using TTarget = TTgt;
  53. TBasicContext() {
  54. Vector.reserve(64);
  55. }
  56. TVector<TElement> Vector;
  57. };
  58. class TKeySortContext: public TBasicContext<TStringBuf, const TDict> {
  59. public:
  60. using TGuard = TContextGuard<TKeySortContext>;
  61. bool Process(const TDict& self);
  62. static bool Needed(const TDict& self) {
  63. return self.size();
  64. }
  65. };
  66. class TSelfOverrideContext: public TBasicContext<TValue, TValue::TScCore> {
  67. public:
  68. using TGuard = TContextGuard<TSelfOverrideContext>;
  69. bool Process(TValue::TScCore& self);
  70. static bool Needed(const TValue::TScCore& self) {
  71. return self.HasChildren();
  72. }
  73. };
  74. class TSelfLoopContext: public TBasicContext<const void*, const TValue::TScCore> {
  75. public:
  76. enum class EMode {
  77. Assert, Throw, Abort, Stderr
  78. };
  79. using TGuard = TContextGuard<TSelfLoopContext>;
  80. bool Process(const TValue::TScCore& self);
  81. static bool Needed(const TValue::TScCore& self) {
  82. return self.HasChildren();
  83. }
  84. public:
  85. EMode ReportingMode = EMode::Assert;
  86. };
  87. }
  88. }