SkNx: kth<...>() -> [...]
authormtklein <mtklein@chromium.org>
Sun, 21 Feb 2016 18:54:19 +0000 (10:54 -0800)
committerCommit bot <commit-bot@chromium.org>
Sun, 21 Feb 2016 18:54:19 +0000 (10:54 -0800)
Just some syntax cleanup.  No real change: kth<...>() was calling [...] already.

BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1714363002
CQ_EXTRA_TRYBOTS=client.skia:Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Release-SKNX_NO_SIMD-Trybot

Review URL: https://codereview.chromium.org/1714363002

14 files changed:
gm/showmiplevels.cpp
src/core/SkColor.cpp
src/core/SkColorMatrixFilterRowMajor255.cpp
src/core/SkGeometry.cpp
src/core/SkNx.h
src/core/SkPM4fPriv.h
src/core/SkScan_Hairline.cpp
src/core/SkXfermode.cpp
src/core/SkXfermode4f.cpp
src/opts/Sk4px_none.h
src/opts/SkNx_neon.h
src/opts/SkNx_sse.h
src/opts/SkXfermode_opts.h
tests/SkNxTest.cpp

index 27d47e5..d3462b7 100644 (file)
@@ -66,8 +66,8 @@ static SkBitmap make_bitmap3(int w, int h) {
     SkScalar s = SkIntToScalar(w);
     Sk4f p(s, -s, -s, s);
     Sk4f d(5);
-    while (p.kth<1>() < s) {
-        canvas.drawLine(p.kth<0>(),p.kth<1>(), p.kth<2>(), p.kth<3>(), paint);
+    while (p[1] < s) {
+        canvas.drawLine(p[0],p[1], p[2], p[3], paint);
         p = p + d;
     }
     return bm;
index d88950b..497c328 100644 (file)
@@ -168,7 +168,7 @@ SkColor4f SkColor4f::Pin(float a, float r, float g, float b) {
 
 SkPM4f SkColor4f::premul() const {
     auto src = Sk4f::Load(this->pin().vec());
-    float srcAlpha = src.kth<0>();  // need the pinned version of our alpha
+    float srcAlpha = src[0];  // need the pinned version of our alpha
     src = src * Sk4f(1, srcAlpha, srcAlpha, srcAlpha);
 
 #ifdef SK_PMCOLOR_IS_BGRA
index ff95bf1..e2545c2 100644 (file)
@@ -66,11 +66,11 @@ static Sk4f scale_rgb(float scale) {
 }
 
 static Sk4f premul(const Sk4f& x) {
-    return x * scale_rgb(x.kth<SkPM4f::A>());
+    return x * scale_rgb(x[SkPM4f::A]);
 }
 
 static Sk4f unpremul(const Sk4f& x) {
-    return x * scale_rgb(1 / x.kth<SkPM4f::A>());  // TODO: fast/approx invert?
+    return x * scale_rgb(1 / x[SkPM4f::A]);  // TODO: fast/approx invert?
 }
 
 static Sk4f clamp_0_1(const Sk4f& x) {
@@ -98,7 +98,7 @@ void filter_span(const float array[], const T src[], int count, T dst[]) {
 
     for (int i = 0; i < count; i++) {
         Sk4f srcf = Adaptor::To4f(src[i]);
-        float srcA = srcf.kth<SkPM4f::A>();
+        float srcA = srcf[SkPM4f::A];
 
         if (0 == srcA) {
             dst[i] = matrix_translate_pmcolor;
@@ -108,10 +108,10 @@ void filter_span(const float array[], const T src[], int count, T dst[]) {
             srcf = unpremul(srcf);
         }
 
-        Sk4f r4 = srcf.kth<SK_R32_SHIFT/8>();
-        Sk4f g4 = srcf.kth<SK_G32_SHIFT/8>();
-        Sk4f b4 = srcf.kth<SK_B32_SHIFT/8>();
-        Sk4f a4 = srcf.kth<SK_A32_SHIFT/8>();
+        Sk4f r4 = srcf[SK_R32_SHIFT/8];
+        Sk4f g4 = srcf[SK_G32_SHIFT/8];
+        Sk4f b4 = srcf[SK_B32_SHIFT/8];
+        Sk4f a4 = srcf[SK_A32_SHIFT/8];
 
         // apply matrix
         Sk4f dst4 = c0 * r4 + c1 * g4 + c2 * b4 + c3 * a4 + c4;
index 809ed19..7256b9e 100644 (file)
@@ -1029,7 +1029,7 @@ void SkConic::chopAt(SkScalar t1, SkScalar t2, SkConic* dst) const {
     dst->fPts[1] = to_point(bXY / bZZ);
     dst->fPts[2] = to_point(cXY / cZZ);
     Sk2s ww = bZZ / (aZZ * cZZ).sqrt();
-    dst->fW = ww.kth<0>();
+    dst->fW = ww[0];
 }
 
 SkPoint SkConic::evalAt(SkScalar t) const {
index 166557d..4ad119a 100644 (file)
@@ -74,8 +74,6 @@ public:
         return k < N/2 ? fLo[k] : fHi[k-N/2];
     }
 
-    template <int k> T kth() const { return (*this)[k]; }
-
     bool allTrue() const { return fLo.allTrue() && fHi.allTrue(); }
     bool anyTrue() const { return fLo.anyTrue() || fHi.anyTrue(); }
     SkNx thenElse(const SkNx& t, const SkNx& e) const {
@@ -139,8 +137,6 @@ public:
         return fVal;
     }
 
-    template <int k> T kth() const { return (*this)[k]; }
-
     bool allTrue() const { return fVal != 0; }
     bool anyTrue() const { return fVal != 0; }
     SkNx thenElse(const SkNx& t, const SkNx& e) const { return fVal != 0 ? t : e; }
index 24d0736..b39891e 100644 (file)
 #include "SkNx.h"
 
 static inline float get_alpha(const Sk4f& f4) {
-    return f4.kth<SkPM4f::A>();
+    return f4[SkPM4f::A];
 }
 
 static inline Sk4f set_alpha(const Sk4f& f4, float alpha) {
     static_assert(3 == SkPM4f::A, "");
-    return Sk4f(f4.kth<0>(), f4.kth<1>(), f4.kth<2>(), alpha);
+    return Sk4f(f4[0], f4[1], f4[2], alpha);
 }
 
 static inline uint32_t to_4b(const Sk4f& f4) {
index 2b2194b..9b21c42 100644 (file)
@@ -326,7 +326,7 @@ static SkRect compute_nocheck_cubic_bounds(const SkPoint pts[4]) {
         min = Sk2s::Min(min, pair);
         max = Sk2s::Max(max, pair);
     }
-    return { min.kth<0>(), min.kth<1>(), max.kth<0>(), max.kth<1>() };
+    return { min[0], min[1], max[0], max[1] };
 }
 
 static bool is_inverted(const SkRect& r) {
index 07c4e16..7f89327 100644 (file)
@@ -50,15 +50,15 @@ static inline int clamp_div255round(int prod) {
 ///////////////////////////////////////////////////////////////////////////////
 #include "SkNx.h"
 
-static Sk4f     alpha(const Sk4f& color) { return Sk4f(color.kth<3>()); }
-static Sk4f inv_alpha(const Sk4f& color) { return Sk4f(1 - color.kth<3>()); }
+static Sk4f     alpha(const Sk4f& color) { return Sk4f(color[3]); }
+static Sk4f inv_alpha(const Sk4f& color) { return Sk4f(1 - color[3]); }
 static Sk4f     pin_1(const Sk4f& value) { return Sk4f::Min(value, Sk4f(1)); }
 
 static Sk4f color_alpha(const Sk4f& color, float newAlpha) {
-    return Sk4f(color.kth<0>(), color.kth<1>(), color.kth<2>(), newAlpha);
+    return Sk4f(color[0], color[1], color[2], newAlpha);
 }
 static Sk4f color_alpha(const Sk4f& color, const Sk4f& newAlpha) {
-    return color_alpha(color, newAlpha.kth<3>());
+    return color_alpha(color, newAlpha[3]);
 }
 
 static Sk4f set_argb(float a, float r, float g, float b) {
@@ -264,15 +264,15 @@ static inline void SetLum(float* r, float* g, float* b, float a, float l) {
 }
 
 static Sk4f hue_4f(const Sk4f& s, const Sk4f& d) {
-    float sa = s.kth<SkPM4f::A>();
-    float sr = s.kth<SkPM4f::R>();
-    float sg = s.kth<SkPM4f::G>();
-    float sb = s.kth<SkPM4f::B>();
+    float sa = s[SkPM4f::A];
+    float sr = s[SkPM4f::R];
+    float sg = s[SkPM4f::G];
+    float sb = s[SkPM4f::B];
     
-    float da = d.kth<SkPM4f::A>();
-    float dr = d.kth<SkPM4f::R>();
-    float dg = d.kth<SkPM4f::G>();
-    float db = d.kth<SkPM4f::B>();
+    float da = d[SkPM4f::A];
+    float dr = d[SkPM4f::R];
+    float dg = d[SkPM4f::G];
+    float db = d[SkPM4f::B];
 
     float Sr = sr;
     float Sg = sg;
@@ -285,15 +285,15 @@ static Sk4f hue_4f(const Sk4f& s, const Sk4f& d) {
 }
 
 static Sk4f saturation_4f(const Sk4f& s, const Sk4f& d) {
-    float sa = s.kth<SkPM4f::A>();
-    float sr = s.kth<SkPM4f::R>();
-    float sg = s.kth<SkPM4f::G>();
-    float sb = s.kth<SkPM4f::B>();
+    float sa = s[SkPM4f::A];
+    float sr = s[SkPM4f::R];
+    float sg = s[SkPM4f::G];
+    float sb = s[SkPM4f::B];
     
-    float da = d.kth<SkPM4f::A>();
-    float dr = d.kth<SkPM4f::R>();
-    float dg = d.kth<SkPM4f::G>();
-    float db = d.kth<SkPM4f::B>();
+    float da = d[SkPM4f::A];
+    float dr = d[SkPM4f::R];
+    float dg = d[SkPM4f::G];
+    float db = d[SkPM4f::B];
     
     float Dr = dr;
     float Dg = dg;
@@ -306,15 +306,15 @@ static Sk4f saturation_4f(const Sk4f& s, const Sk4f& d) {
 }
 
 static Sk4f color_4f(const Sk4f& s, const Sk4f& d) {
-    float sa = s.kth<SkPM4f::A>();
-    float sr = s.kth<SkPM4f::R>();
-    float sg = s.kth<SkPM4f::G>();
-    float sb = s.kth<SkPM4f::B>();
+    float sa = s[SkPM4f::A];
+    float sr = s[SkPM4f::R];
+    float sg = s[SkPM4f::G];
+    float sb = s[SkPM4f::B];
     
-    float da = d.kth<SkPM4f::A>();
-    float dr = d.kth<SkPM4f::R>();
-    float dg = d.kth<SkPM4f::G>();
-    float db = d.kth<SkPM4f::B>();
+    float da = d[SkPM4f::A];
+    float dr = d[SkPM4f::R];
+    float dg = d[SkPM4f::G];
+    float db = d[SkPM4f::B];
 
     float Sr = sr;
     float Sg = sg;
@@ -328,15 +328,15 @@ static Sk4f color_4f(const Sk4f& s, const Sk4f& d) {
 }
 
 static Sk4f luminosity_4f(const Sk4f& s, const Sk4f& d) {
-    float sa = s.kth<SkPM4f::A>();
-    float sr = s.kth<SkPM4f::R>();
-    float sg = s.kth<SkPM4f::G>();
-    float sb = s.kth<SkPM4f::B>();
+    float sa = s[SkPM4f::A];
+    float sr = s[SkPM4f::R];
+    float sg = s[SkPM4f::G];
+    float sb = s[SkPM4f::B];
     
-    float da = d.kth<SkPM4f::A>();
-    float dr = d.kth<SkPM4f::R>();
-    float dg = d.kth<SkPM4f::G>();
-    float db = d.kth<SkPM4f::B>();
+    float da = d[SkPM4f::A];
+    float dr = d[SkPM4f::R];
+    float dg = d[SkPM4f::G];
+    float db = d[SkPM4f::B];
     
     float Dr = dr;
     float Dg = dg;
index b7f2913..1f6c674 100644 (file)
@@ -203,10 +203,10 @@ template <DstType D> void src_1(const SkXfermode::PM4fState& state, uint32_t dst
             const Sk4f& s4_255 = s4 * Sk4f(255);
             while (count >= 4) {
                 Sk4f aa4 = SkNx_cast<float>(Sk4b::Load(aa)) * Sk4f(1/255.f);
-                Sk4f r0 = lerp(s4_255, to_4f(dst[0]), Sk4f(aa4.kth<0>())) + Sk4f(0.5f);
-                Sk4f r1 = lerp(s4_255, to_4f(dst[1]), Sk4f(aa4.kth<1>())) + Sk4f(0.5f);
-                Sk4f r2 = lerp(s4_255, to_4f(dst[2]), Sk4f(aa4.kth<2>())) + Sk4f(0.5f);
-                Sk4f r3 = lerp(s4_255, to_4f(dst[3]), Sk4f(aa4.kth<3>())) + Sk4f(0.5f);
+                Sk4f r0 = lerp(s4_255, to_4f(dst[0]), Sk4f(aa4[0])) + Sk4f(0.5f);
+                Sk4f r1 = lerp(s4_255, to_4f(dst[1]), Sk4f(aa4[1])) + Sk4f(0.5f);
+                Sk4f r2 = lerp(s4_255, to_4f(dst[2]), Sk4f(aa4[2])) + Sk4f(0.5f);
+                Sk4f r3 = lerp(s4_255, to_4f(dst[3]), Sk4f(aa4[3])) + Sk4f(0.5f);
                 Sk4f_ToBytes((uint8_t*)dst, r0, r1, r2, r3);
                 
                 dst += 4;
@@ -221,10 +221,10 @@ template <DstType D> void src_1(const SkXfermode::PM4fState& state, uint32_t dst
                  *  it would be faster (and possibly allow more code sharing with kLinear) to
                  *  stay in that space.
                  */
-                Sk4f r0 = lerp(s4, load_dst<D>(dst[0]), Sk4f(aa4.kth<0>()));
-                Sk4f r1 = lerp(s4, load_dst<D>(dst[1]), Sk4f(aa4.kth<1>()));
-                Sk4f r2 = lerp(s4, load_dst<D>(dst[2]), Sk4f(aa4.kth<2>()));
-                Sk4f r3 = lerp(s4, load_dst<D>(dst[3]), Sk4f(aa4.kth<3>()));
+                Sk4f r0 = lerp(s4, load_dst<D>(dst[0]), Sk4f(aa4[0]));
+                Sk4f r1 = lerp(s4, load_dst<D>(dst[1]), Sk4f(aa4[1]));
+                Sk4f r2 = lerp(s4, load_dst<D>(dst[2]), Sk4f(aa4[2]));
+                Sk4f r3 = lerp(s4, load_dst<D>(dst[3]), Sk4f(aa4[3]));
                 Sk4f_ToBytes((uint8_t*)dst,
                              linear_unit_to_srgb_255f(r0),
                              linear_unit_to_srgb_255f(r1),
index b43ee87..10c3ded 100644 (file)
@@ -40,10 +40,10 @@ inline void Sk4px::store2(SkPMColor px[2]) const { memcpy(px, this,  8); }
 inline void Sk4px::store1(SkPMColor px[1]) const { memcpy(px, this,  4); }
 
 inline Sk4px::Wide Sk4px::widenLo() const {
-    return Sk16h(this->kth< 0>(), this->kth< 1>(), this->kth< 2>(), this->kth< 3>(),
-                 this->kth< 4>(), this->kth< 5>(), this->kth< 6>(), this->kth< 7>(),
-                 this->kth< 8>(), this->kth< 9>(), this->kth<10>(), this->kth<11>(),
-                 this->kth<12>(), this->kth<13>(), this->kth<14>(), this->kth<15>());
+    return Sk16h((*this)[ 0], (*this)[ 1], (*this)[ 2], (*this)[ 3],
+                 (*this)[ 4], (*this)[ 5], (*this)[ 6], (*this)[ 7],
+                 (*this)[ 8], (*this)[ 9], (*this)[10], (*this)[11],
+                 (*this)[12], (*this)[13], (*this)[14], (*this)[15]);
 }
 
 inline Sk4px::Wide Sk4px::widenHi() const { return this->widenLo() << 8; }
@@ -56,10 +56,10 @@ inline Sk4px::Wide Sk4px::mulWiden(const Sk16b& other) const {
 
 inline Sk4px Sk4px::Wide::addNarrowHi(const Sk16h& other) const {
     Sk4px::Wide r = (*this + other) >> 8;
-    return Sk16b(r.kth< 0>(), r.kth< 1>(), r.kth< 2>(), r.kth< 3>(),
-                 r.kth< 4>(), r.kth< 5>(), r.kth< 6>(), r.kth< 7>(),
-                 r.kth< 8>(), r.kth< 9>(), r.kth<10>(), r.kth<11>(),
-                 r.kth<12>(), r.kth<13>(), r.kth<14>(), r.kth<15>());
+    return Sk16b(r[ 0], r[ 1], r[ 2], r[ 3],
+                 r[ 4], r[ 5], r[ 6], r[ 7],
+                 r[ 8], r[ 9], r[10], r[11],
+                 r[12], r[13], r[14], r[15]);
 }
 
 inline Sk4px Sk4px::Wide::div255() const {
@@ -70,10 +70,10 @@ inline Sk4px Sk4px::Wide::div255() const {
 
 inline Sk4px Sk4px::alphas() const {
     static_assert(SK_A32_SHIFT == 24, "This method assumes little-endian.");
-    return Sk16b(this->kth< 3>(), this->kth< 3>(), this->kth< 3>(), this->kth< 3>(),
-                 this->kth< 7>(), this->kth< 7>(), this->kth< 7>(), this->kth< 7>(),
-                 this->kth<11>(), this->kth<11>(), this->kth<11>(), this->kth<11>(),
-                 this->kth<15>(), this->kth<15>(), this->kth<15>(), this->kth<15>());
+    return Sk16b((*this)[ 3], (*this)[ 3], (*this)[ 3], (*this)[ 3],
+                 (*this)[ 7], (*this)[ 7], (*this)[ 7], (*this)[ 7],
+                 (*this)[11], (*this)[11], (*this)[11], (*this)[11],
+                 (*this)[15], (*this)[15], (*this)[15], (*this)[15]);
 }
 
 inline Sk4px Sk4px::Load4Alphas(const SkAlpha a[4]) {
@@ -92,18 +92,18 @@ inline Sk4px Sk4px::Load2Alphas(const SkAlpha a[2]) {
 
 inline Sk4px Sk4px::zeroAlphas() const {
     static_assert(SK_A32_SHIFT == 24, "This method assumes little-endian.");
-    return Sk16b(this->kth< 0>(), this->kth< 1>(), this->kth< 2>(), 0,
-                 this->kth< 4>(), this->kth< 5>(), this->kth< 6>(), 0,
-                 this->kth< 8>(), this->kth< 9>(), this->kth<10>(), 0,
-                 this->kth<12>(), this->kth<13>(), this->kth<14>(), 0);
+    return Sk16b((*this)[ 0], (*this)[ 1], (*this)[ 2], 0,
+                 (*this)[ 4], (*this)[ 5], (*this)[ 6], 0,
+                 (*this)[ 8], (*this)[ 9], (*this)[10], 0,
+                 (*this)[12], (*this)[13], (*this)[14], 0);
 }
 
 inline Sk4px Sk4px::zeroColors() const {
     static_assert(SK_A32_SHIFT == 24, "This method assumes little-endian.");
-    return Sk16b(0,0,0, this->kth< 3>(),
-                 0,0,0, this->kth< 7>(),
-                 0,0,0, this->kth<11>(),
-                 0,0,0, this->kth<15>());
+    return Sk16b(0,0,0, (*this)[ 3],
+                 0,0,0, (*this)[ 7],
+                 0,0,0, (*this)[11],
+                 0,0,0, (*this)[15]);
 }
 
 }  // namespace
index be37baf..1acd7a0 100644 (file)
@@ -111,7 +111,6 @@ public:
         union { float32x2_t v; float fs[2]; } pun = {fVec};
         return pun.fs[k&1];
     }
-    template <int k> float kth() const { return (*this)[k]; }
 
     bool allTrue() const {
         auto v = vreinterpret_u32_f32(fVec);
@@ -203,7 +202,6 @@ public:
         union { float32x4_t v; float fs[4]; } pun = {fVec};
         return pun.fs[k&3];
     }
-    template <int k> float kth() const { return (*this)[k]; }
 
     bool allTrue() const {
         auto v = vreinterpretq_u32_f32(fVec);
@@ -255,7 +253,6 @@ public:
         union { uint16x4_t v; uint16_t us[4]; } pun = {fVec};
         return pun.us[k&3];
     }
-    template <int k> uint16_t kth() const { return (*this)[k]; }
 
     SkNx thenElse(const SkNx& t, const SkNx& e) const {
         return vbsl_u16(fVec, t.fVec, e.fVec);
@@ -294,7 +291,6 @@ public:
         union { uint16x8_t v; uint16_t us[8]; } pun = {fVec};
         return pun.us[k&7];
     }
-    template <int k> uint16_t kth() const { return (*this)[k]; }
 
     SkNx thenElse(const SkNx& t, const SkNx& e) const {
         return vbslq_u16(fVec, t.fVec, e.fVec);
@@ -352,7 +348,6 @@ public:
         union { uint8x16_t v; uint8_t us[16]; } pun = {fVec};
         return pun.us[k&15];
     }
-    template <int k> uint8_t kth() const { return (*this)[k]; }
 
     SkNx thenElse(const SkNx& t, const SkNx& e) const {
         return vbslq_u8(fVec, t.fVec, e.fVec);
index be521a1..b6da080 100644 (file)
@@ -65,7 +65,6 @@ public:
         union { __m128 v; float fs[4]; } pun = {fVec};
         return pun.fs[k&1];
     }
-    template <int k> float kth() const { return (*this)[k]; }
 
     bool allTrue() const { return 0xff == (_mm_movemask_epi8(_mm_castps_si128(fVec)) & 0xff); }
     bool anyTrue() const { return 0x00 != (_mm_movemask_epi8(_mm_castps_si128(fVec)) & 0xff); }
@@ -117,7 +116,6 @@ public:
         union { __m128 v; float fs[4]; } pun = {fVec};
         return pun.fs[k&3];
     }
-    template <int k> float kth() const { return (*this)[k]; }
 
     bool allTrue() const { return 0xffff == _mm_movemask_epi8(_mm_castps_si128(fVec)); }
     bool anyTrue() const { return 0x0000 != _mm_movemask_epi8(_mm_castps_si128(fVec)); }
@@ -159,7 +157,6 @@ public:
         union { __m128i v; int is[4]; } pun = {fVec};
         return pun.is[k&3];
     }
-    template <int k> int kth() const { return (*this)[k]; }
 
     __m128i fVec;
 };
@@ -188,7 +185,6 @@ public:
         union { __m128i v; uint16_t us[8]; } pun = {fVec};
         return pun.us[k&3];
     }
-    template <int k> uint16_t kth() const { return (*this)[k]; }
 
     __m128i fVec;
 };
@@ -232,7 +228,6 @@ public:
         union { __m128i v; uint16_t us[8]; } pun = {fVec};
         return pun.us[k&7];
     }
-    template <int k> uint16_t kth() const { return (*this)[k]; }
 
     __m128i fVec;
 };
@@ -284,7 +279,6 @@ public:
         union { __m128i v; uint8_t us[16]; } pun = {fVec};
         return pun.us[k&15];
     }
-    template <int k> uint8_t kth() const { return (*this)[k]; }
 
     SkNx thenElse(const SkNx& t, const SkNx& e) const {
         return _mm_or_si128(_mm_and_si128   (fVec, t.fVec),
index b049c63..8b64d0b 100644 (file)
@@ -122,7 +122,7 @@ static inline Sk4f a_rgb(const Sk4f& a, const Sk4f& rgb) {
     return a * Sk4f(0,0,0,1) + rgb * Sk4f(1,1,1,0);
 }
 static inline Sk4f alphas(const Sk4f& f) {
-    return f.kth<SK_A32_SHIFT/8>();
+    return f[SK_A32_SHIFT/8];
 }
 
 XFERMODE(ColorDodge) {
index 57e659e..c32659a 100644 (file)
@@ -19,11 +19,11 @@ static void test_Nf(skiatest::Reporter* r) {
         float vals[4];
         v.store(vals);
         bool ok = close(vals[0], a) && close(vals[1], b)
-               && close(v.template kth<0>(), a) && close(v.template kth<1>(), b);
+               && close(   v[0], a) && close(   v[1], b);
         REPORTER_ASSERT(r, ok);
         if (N == 4) {
             ok = close(vals[2], c) && close(vals[3], d)
-              && close(v.template kth<2>(), c) && close(v.template kth<3>(), d);
+              && close(   v[2], c) && close(   v[3], d);
             REPORTER_ASSERT(r, ok);
         }
     };
@@ -92,10 +92,10 @@ void test_Ni(skiatest::Reporter* r) {
           case 2: REPORTER_ASSERT(r, vals[0] == a && vals[1] == b);
         }
         switch (N) {
-          case 8: REPORTER_ASSERT(r, v.template kth<4>() == e && v.template kth<5>() == f &&
-                                     v.template kth<6>() == g && v.template kth<7>() == h);
-          case 4: REPORTER_ASSERT(r, v.template kth<2>() == c && v.template kth<3>() == d);
-          case 2: REPORTER_ASSERT(r, v.template kth<0>() == a && v.template kth<1>() == b);
+          case 8: REPORTER_ASSERT(r, v[4] == e && v[5] == f &&
+                                     v[6] == g && v[7] == h);
+          case 4: REPORTER_ASSERT(r, v[2] == c && v[3] == d);
+          case 2: REPORTER_ASSERT(r, v[0] == a && v[1] == b);
         }
     };
 
@@ -118,7 +118,7 @@ void test_Ni(skiatest::Reporter* r) {
     assert_eq(a >> 2, 0,0,0,1,1,1,1,2);
     assert_eq(a << 1, 2,4,6,8,10,12,14,16);
 
-    REPORTER_ASSERT(r, a.template kth<1>() == 2);
+    REPORTER_ASSERT(r, a[1] == 2);
 }
 
 DEF_TEST(SkNx, r) {
@@ -136,8 +136,8 @@ DEF_TEST(SkNi_min_lt, r) {
     for (int a = 0; a < (1<<8); a++) {
     for (int b = 0; b < (1<<8); b++) {
         Sk16b aw(a), bw(b);
-        REPORTER_ASSERT(r, Sk16b::Min(aw, bw).kth<0>() == SkTMin(a, b));
-        REPORTER_ASSERT(r, !(aw < bw).kth<0>() == !(a < b));
+        REPORTER_ASSERT(r, Sk16b::Min(aw, bw)[0] == SkTMin(a, b));
+        REPORTER_ASSERT(r, !(aw < bw)[0] == !(a < b));
     }}
 
     // Exhausting the 16x16 bit space is kind of slow, so only do that in release builds.
@@ -146,12 +146,12 @@ DEF_TEST(SkNi_min_lt, r) {
     for (int i = 0; i < (1<<16); i++) {
         uint16_t a = rand.nextU() >> 16,
                  b = rand.nextU() >> 16;
-        REPORTER_ASSERT(r, Sk16h::Min(Sk16h(a), Sk16h(b)).kth<0>() == SkTMin(a, b));
+        REPORTER_ASSERT(r, Sk16h::Min(Sk16h(a), Sk16h(b))[0] == SkTMin(a, b));
     }
 #else
     for (int a = 0; a < (1<<16); a++) {
     for (int b = 0; b < (1<<16); b++) {
-        REPORTER_ASSERT(r, Sk16h::Min(Sk16h(a), Sk16h(b)).kth<0>() == SkTMin(a, b));
+        REPORTER_ASSERT(r, Sk16h::Min(Sk16h(a), Sk16h(b))[0] == SkTMin(a, b));
     }}
 #endif
 }
@@ -163,7 +163,7 @@ DEF_TEST(SkNi_saturatedAdd, r) {
         if (exact > 255) { exact = 255; }
         if (exact <   0) { exact =   0; }
 
-        REPORTER_ASSERT(r, Sk16b(a).saturatedAdd(Sk16b(b)).kth<0>() == exact);
+        REPORTER_ASSERT(r, Sk16b(a).saturatedAdd(Sk16b(b))[0] == exact);
     }
     }
 }
@@ -178,11 +178,11 @@ DEF_TEST(Sk4px_muldiv255round, r) {
              bv = Sk4px::DupAlpha(b);
 
         // This way should always be exactly correct.
-        int correct = (av * bv).div255().kth<0>();
+        int correct = (av * bv).div255()[0];
         REPORTER_ASSERT(r, correct == exact);
 
         // We're a bit more flexible on this method: correct for 0 or 255, otherwise off by <=1.
-        int fast = av.approxMulDiv255(bv).kth<0>();
+        int fast = av.approxMulDiv255(bv)[0];
         REPORTER_ASSERT(r, fast-exact >= -1 && fast-exact <= 1);
         if (a == 0 || a == 255 || b == 0 || b == 255) {
             REPORTER_ASSERT(r, fast == exact);
@@ -209,18 +209,18 @@ DEF_TEST(Sk4px_widening, r) {
 
 DEF_TEST(SkNx_abs, r) {
     auto fs = Sk4f(0.0f, -0.0f, 2.0f, -4.0f).abs();
-    REPORTER_ASSERT(r, fs.kth<0>() == 0.0f);
-    REPORTER_ASSERT(r, fs.kth<1>() == 0.0f);
-    REPORTER_ASSERT(r, fs.kth<2>() == 2.0f);
-    REPORTER_ASSERT(r, fs.kth<3>() == 4.0f);
+    REPORTER_ASSERT(r, fs[0] == 0.0f);
+    REPORTER_ASSERT(r, fs[1] == 0.0f);
+    REPORTER_ASSERT(r, fs[2] == 2.0f);
+    REPORTER_ASSERT(r, fs[3] == 4.0f);
 }
 
 DEF_TEST(SkNx_floor, r) {
     auto fs = Sk4f(0.4f, -0.4f, 0.6f, -0.6f).floor();
-    REPORTER_ASSERT(r, fs.kth<0>() ==  0.0f);
-    REPORTER_ASSERT(r, fs.kth<1>() == -1.0f);
-    REPORTER_ASSERT(r, fs.kth<2>() ==  0.0f);
-    REPORTER_ASSERT(r, fs.kth<3>() == -1.0f);
+    REPORTER_ASSERT(r, fs[0] ==  0.0f);
+    REPORTER_ASSERT(r, fs[1] == -1.0f);
+    REPORTER_ASSERT(r, fs[2] ==  0.0f);
+    REPORTER_ASSERT(r, fs[3] == -1.0f);
 }
 
 DEF_TEST(SkNx_shuffle, r) {
@@ -260,19 +260,19 @@ DEF_TEST(SkNx_u16_float, r) {
         // u16 --> float
         auto h4 = Sk4h(15, 17, 257, 65535);
         auto f4 = SkNx_cast<float>(h4);
-        REPORTER_ASSERT(r, f4.kth<0>() == 15.0f);
-        REPORTER_ASSERT(r, f4.kth<1>() == 17.0f);
-        REPORTER_ASSERT(r, f4.kth<2>() == 257.0f);
-        REPORTER_ASSERT(r, f4.kth<3>() == 65535.0f);
+        REPORTER_ASSERT(r, f4[0] == 15.0f);
+        REPORTER_ASSERT(r, f4[1] == 17.0f);
+        REPORTER_ASSERT(r, f4[2] == 257.0f);
+        REPORTER_ASSERT(r, f4[3] == 65535.0f);
     }
     {
         // float -> u16
         auto f4 = Sk4f(15, 17, 257, 65535);
         auto h4 = SkNx_cast<uint16_t>(f4);
-        REPORTER_ASSERT(r, h4.kth<0>() == 15);
-        REPORTER_ASSERT(r, h4.kth<1>() == 17);
-        REPORTER_ASSERT(r, h4.kth<2>() == 257);
-        REPORTER_ASSERT(r, h4.kth<3>() == 65535);
+        REPORTER_ASSERT(r, h4[0] == 15);
+        REPORTER_ASSERT(r, h4[1] == 17);
+        REPORTER_ASSERT(r, h4[2] == 257);
+        REPORTER_ASSERT(r, h4[3] == 65535);
     }
 
     // starting with any u16 value, we should be able to have a perfect round-trip in/out of floats