UnicodeCharRanges.h 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. //===--- UnicodeCharRanges.h - Types and functions for character ranges ---===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #ifndef LLVM_SUPPORT_UNICODECHARRANGES_H
  9. #define LLVM_SUPPORT_UNICODECHARRANGES_H
  10. #include "llvm/ADT/ArrayRef.h"
  11. #include "llvm/Support/Compiler.h"
  12. #include "llvm/Support/Debug.h"
  13. #include "llvm/Support/raw_ostream.h"
  14. #include <algorithm>
  15. #define DEBUG_TYPE "unicode"
  16. namespace llvm {
  17. namespace sys {
  18. /// Represents a closed range of Unicode code points [Lower, Upper].
  19. struct UnicodeCharRange {
  20. uint32_t Lower;
  21. uint32_t Upper;
  22. };
  23. inline bool operator<(uint32_t Value, UnicodeCharRange Range) {
  24. return Value < Range.Lower;
  25. }
  26. inline bool operator<(UnicodeCharRange Range, uint32_t Value) {
  27. return Range.Upper < Value;
  28. }
  29. /// Holds a reference to an ordered array of UnicodeCharRange and allows
  30. /// to quickly check if a code point is contained in the set represented by this
  31. /// array.
  32. class UnicodeCharSet {
  33. public:
  34. typedef ArrayRef<UnicodeCharRange> CharRanges;
  35. /// Constructs a UnicodeCharSet instance from an array of
  36. /// UnicodeCharRanges.
  37. ///
  38. /// Array pointed by \p Ranges should have the lifetime at least as long as
  39. /// the UnicodeCharSet instance, and should not change. Array is validated by
  40. /// the constructor, so it makes sense to create as few UnicodeCharSet
  41. /// instances per each array of ranges, as possible.
  42. #ifdef NDEBUG
  43. // FIXME: This could use constexpr + static_assert. This way we
  44. // may get rid of NDEBUG in this header. Unfortunately there are some
  45. // problems to get this working with MSVC 2013. Change this when
  46. // the support for MSVC 2013 is dropped.
  47. constexpr UnicodeCharSet(CharRanges Ranges) : Ranges(Ranges) {}
  48. #else
  49. UnicodeCharSet(CharRanges Ranges) : Ranges(Ranges) {
  50. assert(rangesAreValid());
  51. }
  52. #endif
  53. /// Returns true if the character set contains the Unicode code point
  54. /// \p C.
  55. bool contains(uint32_t C) const {
  56. return std::binary_search(Ranges.begin(), Ranges.end(), C);
  57. }
  58. private:
  59. /// Returns true if each of the ranges is a proper closed range
  60. /// [min, max], and if the ranges themselves are ordered and non-overlapping.
  61. bool rangesAreValid() const {
  62. uint32_t Prev = 0;
  63. for (CharRanges::const_iterator I = Ranges.begin(), E = Ranges.end();
  64. I != E; ++I) {
  65. if (I != Ranges.begin() && Prev >= I->Lower) {
  66. LLVM_DEBUG(dbgs() << "Upper bound 0x");
  67. LLVM_DEBUG(dbgs().write_hex(Prev));
  68. LLVM_DEBUG(dbgs() << " should be less than succeeding lower bound 0x");
  69. LLVM_DEBUG(dbgs().write_hex(I->Lower) << "\n");
  70. return false;
  71. }
  72. if (I->Upper < I->Lower) {
  73. LLVM_DEBUG(dbgs() << "Upper bound 0x");
  74. LLVM_DEBUG(dbgs().write_hex(I->Lower));
  75. LLVM_DEBUG(dbgs() << " should not be less than lower bound 0x");
  76. LLVM_DEBUG(dbgs().write_hex(I->Upper) << "\n");
  77. return false;
  78. }
  79. Prev = I->Upper;
  80. }
  81. return true;
  82. }
  83. const CharRanges Ranges;
  84. };
  85. } // namespace sys
  86. } // namespace llvm
  87. #undef DEBUG_TYPE // "unicode"
  88. #endif // LLVM_SUPPORT_UNICODECHARRANGES_H