text: // Copyright 2018 Google LLC.
  // Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
  #ifndef SkPDFGlyphUse_DEFINED
  #define SkPDFGlyphUse_DEFINED
  
  #include "include/core/SkTypes.h"
  #include "src/utils/SkBitSet.h"
  
  class SkPDFGlyphUse {
   public:
    SkPDFGlyphUse() : fBitSet(0) {}
    SkPDFGlyphUse(SkGlyphID firstNonZero, SkGlyphID lastGlyph)
        : fBitSet(lastGlyph - firstNonZero + 2), fFirstNonZero(firstNonZero), fLastGlyph(lastGlyph) {
      SkASSERT(firstNonZero >= 1);
    }
    ~SkPDFGlyphUse() = default;
    SkPDFGlyphUse(SkPDFGlyphUse&&) = default;
    SkPDFGlyphUse& operator=(SkPDFGlyphUse&&) = default;
  
    SkGlyphID firstNonZero() const { return fFirstNonZero; }
    SkGlyphID lastGlyph() const { return fLastGlyph; }
    void set(SkGlyphID gid) { fBitSet.set(this->toCode(gid)); }
    bool has(SkGlyphID gid) const { return fBitSet.test(this->toCode(gid)); }
  
    template <typename FN>
    void getSetValues(FN f) const {
      if (fFirstNonZero == 1) {
        return fBitSet.forEachSetIndex(std::move(f));
      }
      uint16_t offset = fFirstNonZero - 1;
      fBitSet.forEachSetIndex([&f, offset](unsigned v) { f(v == 0 ? v : v + offset); });
    }
  
   private:
    SkBitSet fBitSet;
    SkGlyphID fFirstNonZero = 0;
    SkGlyphID fLastGlyph = 0;
  
    uint16_t toCode(SkGlyphID gid) const {
      if (gid == 0 || fFirstNonZero == 1) {
        return gid;
      }
      SkASSERT(gid >= fFirstNonZero && gid <= fLastGlyph);
      return gid - fFirstNonZero + 1;
    }
    SkPDFGlyphUse(const SkPDFGlyphUse&) = delete;
    SkPDFGlyphUse& operator=(const SkPDFGlyphUse&) = delete;
  };
  #endif  // SkPDFGlyphUse_DEFINED
  