unicode_table.h 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. #pragma once
  2. #include <util/system/yassert.h>
  3. #include <util/system/defaults.h>
  4. #include <util/generic/typetraits.h>
  5. namespace NUnicodeTable {
  6. template <class Value>
  7. struct TValueSelector;
  8. template <class Value>
  9. struct TValueSelector {
  10. using TStored = const Value;
  11. using TValueRef = const Value&;
  12. using TValuePtr = const Value*;
  13. static inline TValueRef Get(TValuePtr val) {
  14. return *val;
  15. }
  16. };
  17. template <class Value>
  18. struct TValueSelector<const Value*> {
  19. using TStored = const Value[];
  20. using TValueRef = const Value*;
  21. using TValuePtr = const Value*;
  22. static inline TValueRef Get(TValuePtr val) {
  23. return val;
  24. }
  25. };
  26. template <class Value>
  27. struct TValues {
  28. using TSelector = TValueSelector<Value>;
  29. using TStored = typename TSelector::TStored;
  30. using TValueRef = typename TSelector::TValueRef;
  31. using TValuePtr = typename TSelector::TValuePtr;
  32. using TData = const TValuePtr*;
  33. static inline TValuePtr Get(TData table, size_t index) {
  34. static_assert(std::is_pointer<TData>::value, "expect std::is_pointer<TData>::value");
  35. return table[index];
  36. }
  37. static inline TValueRef Get(TValuePtr val) {
  38. return TSelector::Get(val);
  39. }
  40. };
  41. template <int Shift, class TChild>
  42. struct TSubtable {
  43. using TStored = typename TChild::TStored;
  44. using TValueRef = typename TChild::TValueRef;
  45. using TValuePtr = typename TChild::TValuePtr;
  46. using TData = const typename TChild::TData*;
  47. static inline TValuePtr Get(TData table, size_t key) {
  48. static_assert(std::is_pointer<TData>::value, "expect std::is_pointer<TData>::value");
  49. return TChild::Get(table[key >> Shift], key & ((1 << Shift) - 1));
  50. }
  51. static inline TValueRef Get(TValuePtr val) {
  52. return TChild::Get(val);
  53. }
  54. };
  55. template <class T>
  56. class TTable {
  57. private:
  58. using TImpl = T;
  59. using TData = typename TImpl::TData;
  60. const TData Data;
  61. const size_t MSize;
  62. public:
  63. using TStored = typename TImpl::TStored;
  64. using TValueRef = typename TImpl::TValueRef;
  65. using TValuePtr = typename TImpl::TValuePtr;
  66. private:
  67. inline TValueRef GetImpl(size_t key) const {
  68. TValuePtr val = TImpl::Get(Data, key);
  69. return TImpl::Get(val);
  70. }
  71. inline TValueRef Get(size_t key) const {
  72. return GetImpl(key);
  73. }
  74. public:
  75. TTable(TData data, size_t size)
  76. : Data(data)
  77. , MSize(size)
  78. {
  79. static_assert(std::is_pointer<TData>::value, "expect std::is_pointer<TData>::value");
  80. }
  81. inline TValueRef Get(size_t key, TValueRef value) const {
  82. if (key >= Size())
  83. return value;
  84. return GetImpl(key);
  85. }
  86. inline TValueRef Get(size_t key, size_t defaultKey) const {
  87. if (key >= Size())
  88. return Get(defaultKey);
  89. return GetImpl(key);
  90. }
  91. inline size_t Size() const {
  92. return MSize;
  93. }
  94. };
  95. const size_t UNICODE_TABLE_SHIFT = 5;
  96. } // namespace NUnicodeTable