mfbt/EnumeratedRange.h
author Morten Stenshorne <mstensho@chromium.org>
Tue, 09 Oct 2018 04:14:13 +0000
changeset 495959 13844f50ee32e17f513b7c1013c2348200e21b8c
parent 347102 97446e8fdc0c5941a1021ee05993546429d3759d
child 505383 6f3709b3878117466168c40affa7bca0b60cf75b
permissions -rw-r--r--
Bug 1496274 [wpt PR 13345] - [LayoutNG] Correct clip-path reference box calculation., a=testonly Automatic update from web-platform-tests[LayoutNG] Correct clip-path reference box calculation. We used coordinates relatively to the line box, while we were expected by the caller to be relative to the containing block. Flipping for writing mode was bogus for NG (but needed by legacy), since NG uses truly physical coordinates. Hardened tests to contain a leading line and padding, and leading content on the first line of the clipped child. Bug: 641907 Change-Id: I2b1b9ff4ea92a6405fcdffcf139842458b46442f Cq-Include-Trybots: luci.chromium.try​:linux_layout_tests_layout_ng Reviewed-on: https://chromium-review.googlesource.com/c/1257913 Reviewed-by: Koji Ishii <kojii@chromium.org> Reviewed-by: Fredrik Söderquist <fs@opera.com> Commit-Queue: Morten Stenshorne <mstensho@chromium.org> Cr-Commit-Position: refs/heads/master@{#596554} -- wpt-commits: e9a0828c85819340f721f121aac19ab8eefa3439 wpt-pr: 13345

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/* Iterator over contiguous enum values */

/*
 * Implements generator functions that create a range to iterate over the values
 * of a scoped or unscoped enum. Unlike IntegerRange, which can only function on
 * the underlying integral type, the elements of the generated sequence will
 * have the type of the enum in question.
 *
 * Note that the enum values should be contiguous in the iterated range;
 * unfortunately there exists no way for EnumeratedRange to enforce this
 * either dynamically or at compile time.
 */

#ifndef mozilla_EnumeratedRange_h
#define mozilla_EnumeratedRange_h

#include <type_traits>

#include "mozilla/ReverseIterator.h"

namespace mozilla {

namespace detail {

template<typename EnumTypeT>
class EnumeratedIterator
{
public:
  typedef typename std::underlying_type<EnumTypeT>::type IntTypeT;

  template<typename EnumType>
  explicit EnumeratedIterator(EnumType aCurrent)
    : mCurrent(aCurrent) { }

  template<typename EnumType>
  explicit EnumeratedIterator(const EnumeratedIterator<EnumType>& aOther)
    : mCurrent(aOther.mCurrent) { }

  EnumTypeT operator*() const { return mCurrent; }

  /* Increment and decrement operators */

  EnumeratedIterator& operator++()
  {
    mCurrent = EnumTypeT(IntTypeT(mCurrent) + IntTypeT(1));
    return *this;
  }
  EnumeratedIterator& operator--()
  {
    mCurrent = EnumTypeT(IntTypeT(mCurrent) - IntTypeT(1));
    return *this;
  }
  EnumeratedIterator operator++(int)
  {
    auto ret = *this;
    mCurrent = EnumTypeT(IntTypeT(mCurrent) + IntTypeT(1));
    return ret;
  }
  EnumeratedIterator operator--(int)
  {
    auto ret = *this;
    mCurrent = EnumTypeT(IntTypeT(mCurrent) - IntTypeT(1));
    return ret;
  }

  /* Comparison operators */

  template<typename EnumType>
  friend bool operator==(const EnumeratedIterator<EnumType>& aIter1,
                         const EnumeratedIterator<EnumType>& aIter2);
  template<typename EnumType>
  friend bool operator!=(const EnumeratedIterator<EnumType>& aIter1,
                         const EnumeratedIterator<EnumType>& aIter2);
  template<typename EnumType>
  friend bool operator<(const EnumeratedIterator<EnumType>& aIter1,
                        const EnumeratedIterator<EnumType>& aIter2);
  template<typename EnumType>
  friend bool operator<=(const EnumeratedIterator<EnumType>& aIter1,
                         const EnumeratedIterator<EnumType>& aIter2);
  template<typename EnumType>
  friend bool operator>(const EnumeratedIterator<EnumType>& aIter1,
                        const EnumeratedIterator<EnumType>& aIter2);
  template<typename EnumType>
  friend bool operator>=(const EnumeratedIterator<EnumType>& aIter1,
                         const EnumeratedIterator<EnumType>& aIter2);

private:
  EnumTypeT mCurrent;
};

template<typename EnumType>
bool operator==(const EnumeratedIterator<EnumType>& aIter1,
                const EnumeratedIterator<EnumType>& aIter2)
{
  return aIter1.mCurrent == aIter2.mCurrent;
}

template<typename EnumType>
bool operator!=(const EnumeratedIterator<EnumType>& aIter1,
                const EnumeratedIterator<EnumType>& aIter2)
{
  return aIter1.mCurrent != aIter2.mCurrent;
}

template<typename EnumType>
bool operator<(const EnumeratedIterator<EnumType>& aIter1,
               const EnumeratedIterator<EnumType>& aIter2)
{
  return aIter1.mCurrent < aIter2.mCurrent;
}

template<typename EnumType>
bool operator<=(const EnumeratedIterator<EnumType>& aIter1,
                const EnumeratedIterator<EnumType>& aIter2)
{
  return aIter1.mCurrent <= aIter2.mCurrent;
}

template<typename EnumType>
bool operator>(const EnumeratedIterator<EnumType>& aIter1,
               const EnumeratedIterator<EnumType>& aIter2)
{
  return aIter1.mCurrent > aIter2.mCurrent;
}

template<typename EnumType>
bool operator>=(const EnumeratedIterator<EnumType>& aIter1,
                const EnumeratedIterator<EnumType>& aIter2)
{
  return aIter1.mCurrent >= aIter2.mCurrent;
}

template<typename EnumTypeT>
class EnumeratedRange
{
public:
  typedef EnumeratedIterator<EnumTypeT> iterator;
  typedef EnumeratedIterator<EnumTypeT> const_iterator;
  typedef ReverseIterator<iterator> reverse_iterator;
  typedef ReverseIterator<const_iterator> const_reverse_iterator;

  template<typename EnumType>
  EnumeratedRange(EnumType aBegin, EnumType aEnd)
    : mBegin(aBegin), mEnd(aEnd) { }

  iterator begin() const { return iterator(mBegin); }
  const_iterator cbegin() const { return begin(); }
  iterator end() const { return iterator(mEnd); }
  const_iterator cend() const { return end(); }
  reverse_iterator rbegin() const { return reverse_iterator(mEnd); }
  const_reverse_iterator crbegin() const { return rbegin(); }
  reverse_iterator rend() const { return reverse_iterator(mBegin); }
  const_reverse_iterator crend() const { return rend(); }

private:
  EnumTypeT mBegin;
  EnumTypeT mEnd;
};

} // namespace detail

#ifdef __GNUC__
// Enums can have an unsigned underlying type, which makes some of the
// comparisons below always true or always false. Temporarily disable
// -Wtype-limits to avoid breaking -Werror builds.
#  pragma GCC diagnostic push
#  pragma GCC diagnostic ignored "-Wtype-limits"
#endif

// Create a range to iterate from aBegin to aEnd, exclusive.
template<typename EnumType>
inline detail::EnumeratedRange<EnumType>
MakeEnumeratedRange(EnumType aBegin, EnumType aEnd)
{
  MOZ_ASSERT(aBegin <= aEnd, "Cannot generate invalid, unbounded range!");
  return detail::EnumeratedRange<EnumType>(aBegin, aEnd);
}

// Create a range to iterate from EnumType(0) to aEnd, exclusive. EnumType(0)
// should exist, but note that there is no way for us to ensure that it does!
template<typename EnumType>
inline detail::EnumeratedRange<EnumType>
MakeEnumeratedRange(EnumType aEnd)
{
  return MakeEnumeratedRange(EnumType(0), aEnd);
}

#ifdef __GNUC__
#  pragma GCC diagnostic pop
#endif

} // namespace mozilla

#endif // mozilla_EnumeratedRange_h