Make SkEnumerate make flatten tuples

The new c++17 only has a single level of destructuring;
append the index instead of nesting it.

Change-Id: I26bb1ca387d1de57233dbf7096dcf4bb7aaedecf
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/254637
Reviewed-by: Ben Wagner <bungeman@google.com>
Commit-Queue: Herb Derby <herb@google.com>
This commit is contained in:
Herb Derby 2019-11-14 13:51:43 -05:00 committed by Skia Commit-Bot
parent ed8ca4ea96
commit 81777ac947
6 changed files with 31 additions and 46 deletions

View File

@ -14,11 +14,20 @@
#include "include/private/SkTLogic.h"
// SkEnumerate returns a tuple with an index and the value returned by the iterator. The index always
// starts at 0.
template <typename Iter, typename C = skstd::monostate>
class SkEnumerate {
using Result = std::tuple<size_t, decltype(*std::declval<Iter>())>;
using Captured = decltype(*std::declval<Iter>());
template <typename> struct is_tuple : std::false_type {};
template <typename... T> struct is_tuple<std::tuple<T...>> : std::true_type {};
static constexpr auto MakeResult(size_t i, Captured&& v) {
if constexpr (is_tuple<Captured>::value) {
return std::tuple_cat(std::tuple<size_t>{i}, std::forward<Captured>(v));
} else {
return std::tuple_cat(std::tuple<size_t>{i},
std::make_tuple(std::forward<Captured>(v)));
}
}
using Result = decltype(MakeResult(0, std::declval<Captured>()));
class Iterator {
public:
@ -33,7 +42,7 @@ class SkEnumerate {
constexpr Iterator operator++(int) { Iterator tmp(*this); operator++(); return tmp; }
constexpr bool operator==(const Iterator& rhs) const { return fIt == rhs.fIt; }
constexpr bool operator!=(const Iterator& rhs) const { return fIt != rhs.fIt; }
constexpr reference operator*() { return std::forward_as_tuple(fIndex, *fIt); }
constexpr reference operator*() { return MakeResult(fIndex, *fIt); }
private:
ptrdiff_t fIndex;
@ -49,7 +58,8 @@ public:
constexpr SkEnumerate(const SkEnumerate& that) = default;
constexpr SkEnumerate& operator=(const SkEnumerate& that) {
fBegin = that.fBegin;
fEnd = that.fEnd; return *this;
fEnd = that.fEnd;
return *this;
}
constexpr Iterator begin() const { return Iterator{0, fBegin}; }
constexpr Iterator end() const { return Iterator{fEnd - fBegin, fEnd}; }

View File

@ -191,9 +191,7 @@ public:
template <typename Fn>
void forEachGlyphID(Fn&& fn) {
for (auto t : SkMakeEnumerate(this->input())) {
size_t i; SkGlyphVariant packedID; SkPoint pos;
std::forward_as_tuple(i, std::tie(packedID, pos)) = t;
for (auto [i, packedID, pos] : SkMakeEnumerate(this->input())) {
fn(i, packedID.packedID(), pos);
}
}

View File

@ -772,10 +772,8 @@ void SkStrikeServer::RemoteStrike::commonMaskLoop(
void SkStrikeServer::RemoteStrike::prepareForMaskDrawing(
SkDrawableGlyphBuffer* drawables, SkSourceGlyphBuffer* rejects) {
for (auto t : SkMakeEnumerate(drawables->input())) {
size_t i; SkPackedGlyphID packedID;
std::forward_as_tuple(i, std::tie(packedID, std::ignore)) = t;
for (auto [i, variant, _] : SkMakeEnumerate(drawables->input())) {
SkPackedGlyphID packedID = variant.packedID();
if (fSentLowGlyphIDs.test(packedID)) {
SkASSERT(fSentGlyphs.find(packedID) != nullptr);
continue;

View File

@ -12,7 +12,6 @@
#include "include/core/SkPoint.h"
#include "include/core/SkTypes.h"
#include "src/core/SkGlyph.h"
#include "src/core/SkGlyphBuffer.h"
#include "src/core/SkSpan.h"
#include <memory>
@ -22,6 +21,7 @@ class SkDrawableGlyphBuffer;
class SkGlyph;
class SkMaskFilter;
class SkPathEffect;
class SkSourceGlyphBuffer;
class SkTypeface;
struct SkGlyphPositionRoundingSpec;
struct SkScalerContextEffects;

View File

@ -103,9 +103,7 @@ DEF_TEST(SkSourceGlyphBufferBasic, reporter) {
auto source = SkMakeZip(glyphIDs, positions);
rejects.setSource(source);
for (auto t : SkMakeEnumerate(rejects.source())) {
size_t i; SkGlyphID glyphID; SkPoint pos;
std::forward_as_tuple(i, std::tie(glyphID, pos)) = t;
for (auto [i, glyphID, pos] : SkMakeEnumerate(rejects.source())) {
REPORTER_ASSERT(reporter, glyphID == std::get<0>(source[i]));
REPORTER_ASSERT(reporter, pos == std::get<1>(source[i]));
}
@ -114,9 +112,7 @@ DEF_TEST(SkSourceGlyphBufferBasic, reporter) {
rejects.reject(2, 100);
rejects.flipRejectsToSource();
REPORTER_ASSERT(reporter, rejects.rejectedMaxDimension() == 100);
for (auto t : SkMakeEnumerate(rejects.source())) {
size_t i; SkGlyphID glyphID; SkPoint pos;
std::forward_as_tuple(i, std::tie(glyphID, pos)) = t;
for (auto [i, glyphID, pos] : SkMakeEnumerate(rejects.source())) {
// This will index 1 and 2 from the original source.
size_t j = i + 1;
REPORTER_ASSERT(reporter, glyphID == std::get<0>(source[j]));
@ -127,9 +123,7 @@ DEF_TEST(SkSourceGlyphBufferBasic, reporter) {
rejects.reject(0, 10);
rejects.flipRejectsToSource();
REPORTER_ASSERT(reporter, rejects.rejectedMaxDimension() == 10);
for (auto t : SkMakeEnumerate(rejects.source())) {
size_t i; SkGlyphID glyphID; SkPoint pos;
std::forward_as_tuple(i, std::tie(glyphID, pos)) = t;
for (auto [i, glyphID, pos] : SkMakeEnumerate(rejects.source())) {
// This will index 1 from the original source.
size_t j = i + 1;
REPORTER_ASSERT(reporter, glyphID == std::get<0>(source[j]));
@ -138,9 +132,7 @@ DEF_TEST(SkSourceGlyphBufferBasic, reporter) {
// Start all over
rejects.setSource(source);
for (auto t : SkMakeEnumerate(rejects.source())) {
size_t i; SkGlyphID glyphID; SkPoint pos;
std::forward_as_tuple(i, std::tie(glyphID, pos)) = t;
for (auto [i, glyphID, pos] : SkMakeEnumerate(rejects.source())) {
REPORTER_ASSERT(reporter, glyphID == std::get<0>(source[i]));
REPORTER_ASSERT(reporter, pos == std::get<1>(source[i]));
}
@ -150,9 +142,7 @@ DEF_TEST(SkSourceGlyphBufferBasic, reporter) {
rejects.reject(2, 100);
rejects.flipRejectsToSource();
REPORTER_ASSERT(reporter, rejects.rejectedMaxDimension() == 100);
for (auto t : SkMakeEnumerate(rejects.source())) {
size_t i; SkGlyphID glyphID; SkPoint pos;
std::forward_as_tuple(i, std::tie(glyphID, pos)) = t;
for (auto [i, glyphID, pos] : SkMakeEnumerate(rejects.source())) {
// This will index 1 and 2 from the original source.
size_t j = i + 1;
REPORTER_ASSERT(reporter, glyphID == std::get<0>(source[j]));
@ -171,9 +161,7 @@ DEF_TEST(SkDrawableGlyphBufferBasic, reporter) {
SkDrawableGlyphBuffer drawable;
drawable.ensureSize(100);
drawable.startSource(source, {100, 100});
for (auto t : SkMakeEnumerate(drawable.input())) {
size_t i; SkGlyphVariant packedID; SkPoint pos;
std::forward_as_tuple(i, std::tie(packedID, pos)) = t;
for (auto [i, packedID, pos] : SkMakeEnumerate(drawable.input())) {
REPORTER_ASSERT(reporter, packedID.packedID().glyphID() == glyphIDs[i]);
REPORTER_ASSERT(reporter, pos == positions[i] + SkPoint::Make(100, 100));
}
@ -185,9 +173,7 @@ DEF_TEST(SkDrawableGlyphBufferBasic, reporter) {
SkMatrix matrix = SkMatrix::MakeScale(0.5);
SkGlyphPositionRoundingSpec rounding{true, kX_SkAxisAlignment};
drawable.startDevice(source, {100, 100}, matrix, rounding);
for (auto t : SkMakeEnumerate(drawable.input())) {
size_t i; SkGlyphVariant packedID; SkPoint pos;
std::forward_as_tuple(i, std::tie(packedID, pos)) = t;
for (auto [i, packedID, pos] : SkMakeEnumerate(drawable.input())) {
REPORTER_ASSERT(reporter, glyphIDs[i] == packedID.packedID().glyphID());
REPORTER_ASSERT(reporter,
pos.x() == positions[i].x() * 0.5 + 50 + SkPackedGlyphID::kSubpixelRound);
@ -199,14 +185,10 @@ DEF_TEST(SkDrawableGlyphBufferBasic, reporter) {
SkDrawableGlyphBuffer drawable;
drawable.ensureSize(100);
drawable.startSource(source, {100, 100});
for (auto t : SkMakeEnumerate(drawable.input())) {
size_t i; SkGlyphVariant packedID; SkPoint pos;
std::forward_as_tuple(i, std::tie(packedID, pos)) = t;
for (auto [i, packedID, pos] : SkMakeEnumerate(drawable.input())) {
drawable.push_back(&glyphs[i], i);
}
for (auto t : SkMakeEnumerate(drawable.drawable())) {
size_t i; SkGlyphVariant glyph; SkPoint pos;
std::forward_as_tuple(i, std::tie(glyph, pos)) = t;
for (auto [i, glyph, pos] : SkMakeEnumerate(drawable.drawable())) {
REPORTER_ASSERT(reporter, glyph.glyph() == &glyphs[i]);
}
}

View File

@ -521,8 +521,7 @@ DEF_TEST(SkMakeZip, reporter) {
{
// Check SkEnumerate and SkMakeZip in ranged for
auto zz = SkMakeZip(A, B, C, D, S);
for (auto [i, t] : SkMakeEnumerate(zz)) {
auto [a, b, c, d, s] = t;
for (auto [i, a, b, c, d, s] : SkMakeEnumerate(zz)) {
REPORTER_ASSERT(reporter, a == A[i]);
REPORTER_ASSERT(reporter, b == B[i]);
REPORTER_ASSERT(reporter, c == C[i]);
@ -534,8 +533,7 @@ DEF_TEST(SkMakeZip, reporter) {
{
// Check SkEnumerate and SkMakeZip in ranged for
const auto& zz = SkMakeZip(A, B, C, D, S);
for (auto [i, t] : SkMakeEnumerate(zz)) {
auto [a, b, c, d, s] = t;
for (auto [i, a, b, c, d, s] : SkMakeEnumerate(zz)) {
REPORTER_ASSERT(reporter, a == A[i]);
REPORTER_ASSERT(reporter, b == B[i]);
REPORTER_ASSERT(reporter, c == C[i]);
@ -546,8 +544,7 @@ DEF_TEST(SkMakeZip, reporter) {
{
// Check SkEnumerate and SkMakeZip in ranged for
for (auto [i, t] : SkMakeEnumerate(SkMakeZip(A, B, C, D, S))) {
auto [a, b, c, d, s] = t;
for (auto [i, a, b, c, d, s] : SkMakeEnumerate(SkMakeZip(A, B, C, D, S))) {
REPORTER_ASSERT(reporter, a == A[i]);
REPORTER_ASSERT(reporter, b == B[i]);
REPORTER_ASSERT(reporter, c == C[i]);