Range.h 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* vim: set ts=8 sts=2 et sw=2 tw=80: */
  3. /* This Source Code Form is subject to the terms of the Mozilla Public
  4. * License, v. 2.0. If a copy of the MPL was not distributed with this
  5. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  6. #ifndef mozilla_Range_h
  7. #define mozilla_Range_h
  8. #include "mozilla/RangedPtr.h"
  9. #include "mozilla/TypeTraits.h"
  10. #include <stddef.h>
  11. namespace mozilla {
  12. // Range<T> is a tuple containing a pointer and a length.
  13. template <typename T>
  14. class Range
  15. {
  16. const RangedPtr<T> mStart;
  17. const RangedPtr<T> mEnd;
  18. public:
  19. Range() : mStart(nullptr, 0), mEnd(nullptr, 0) {}
  20. Range(T* aPtr, size_t aLength)
  21. : mStart(aPtr, aPtr, aPtr + aLength),
  22. mEnd(aPtr + aLength, aPtr, aPtr + aLength)
  23. {}
  24. Range(const RangedPtr<T>& aStart, const RangedPtr<T>& aEnd)
  25. : mStart(aStart.get(), aStart.get(), aEnd.get()),
  26. mEnd(aEnd.get(), aStart.get(), aEnd.get())
  27. {
  28. // Only accept two RangedPtrs within the same range.
  29. aStart.checkIdenticalRange(aEnd);
  30. MOZ_ASSERT(aStart <= aEnd);
  31. }
  32. template<typename U,
  33. class = typename EnableIf<IsConvertible<U (*)[], T (*)[]>::value,
  34. int>::Type>
  35. MOZ_IMPLICIT Range(const Range<U>& aOther)
  36. : mStart(aOther.mStart),
  37. mEnd(aOther.mEnd)
  38. {}
  39. RangedPtr<T> begin() const { return mStart; }
  40. RangedPtr<T> end() const { return mEnd; }
  41. size_t length() const { return mEnd - mStart; }
  42. T& operator[](size_t aOffset) const { return mStart[aOffset]; }
  43. explicit operator bool() const { return mStart != nullptr; }
  44. };
  45. } // namespace mozilla
  46. #endif /* mozilla_Range_h */