Range.h 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this
  4. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. #ifndef mozilla_Range_h
  6. #define mozilla_Range_h
  7. #include "mozilla/RangedPtr.h"
  8. #include "mozilla/TypeTraits.h"
  9. #include "mozilla/Span.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. MOZ_IMPLICIT Range(Span<T> aSpan)
  40. : Range(aSpan.Elements(), aSpan.Length())
  41. {
  42. }
  43. template<typename U,
  44. class = typename EnableIf<IsConvertible<U (*)[], T (*)[]>::value,
  45. int>::Type>
  46. MOZ_IMPLICIT Range(const Span<U>& aSpan)
  47. : Range(aSpan.Elements(), aSpan.Length())
  48. {
  49. }
  50. RangedPtr<T> begin() const { return mStart; }
  51. RangedPtr<T> end() const { return mEnd; }
  52. size_t length() const { return mEnd - mStart; }
  53. T& operator[](size_t aOffset) const { return mStart[aOffset]; }
  54. explicit operator bool() const { return mStart != nullptr; }
  55. operator Span<T>() { return Span<T>(mStart.get(), length()); }
  56. operator Span<const T>() const { return Span<T>(mStart.get(), length()); }
  57. };
  58. template<class T>
  59. Span<T>
  60. MakeSpan(Range<T>& aRange)
  61. {
  62. return aRange;
  63. }
  64. template<class T>
  65. Span<const T>
  66. MakeSpan(const Range<T>& aRange)
  67. {
  68. return aRange;
  69. }
  70. } // namespace mozilla
  71. #endif /* mozilla_Range_h */