diff --git a/src/realm/array.cpp b/src/realm/array.cpp
index 3b4c5f32db1..e3c981049fb 100644
--- a/src/realm/array.cpp
+++ b/src/realm/array.cpp
@@ -550,92 +550,6 @@ void Array::do_ensure_minimum_width(int_fast64_t value)
     }
 }
 
-namespace {
-
-template <size_t width>
-inline int64_t lower_bits()
-{
-    if (width == 1)
-        return 0xFFFFFFFFFFFFFFFFULL;
-    else if (width == 2)
-        return 0x5555555555555555ULL;
-    else if (width == 4)
-        return 0x1111111111111111ULL;
-    else if (width == 8)
-        return 0x0101010101010101ULL;
-    else if (width == 16)
-        return 0x0001000100010001ULL;
-    else if (width == 32)
-        return 0x0000000100000001ULL;
-    else if (width == 64)
-        return 0x0000000000000001ULL;
-    else {
-        REALM_ASSERT_DEBUG(false);
-        return int64_t(-1);
-    }
-}
-
-// Return true if 'value' has an element (of bit-width 'width') which is 0
-template <size_t width>
-inline bool has_zero_element(uint64_t value)
-{
-    uint64_t hasZeroByte;
-    uint64_t lower = lower_bits<width>();
-    uint64_t upper = lower_bits<width>() * 1ULL << (width == 0 ? 0 : (width - 1ULL));
-    hasZeroByte = (value - lower) & ~value & upper;
-    return hasZeroByte != 0;
-}
-
-
-// Finds zero element of bit width 'width'
-template <bool eq, size_t width>
-size_t find_zero(uint64_t v)
-{
-    size_t start = 0;
-    uint64_t hasZeroByte;
-
-    // Bisection optimization, speeds up small bitwidths with high match frequency. More partions than 2 do NOT pay
-    // off because the work done by test_zero() is wasted for the cases where the value exists in first half, but
-    // useful if it exists in last half. Sweet spot turns out to be the widths and partitions below.
-    if (width <= 8) {
-        hasZeroByte = has_zero_element<width>(v | 0xffffffff00000000ULL);
-        if (eq ? !hasZeroByte : (v & 0x00000000ffffffffULL) == 0) {
-            // 00?? -> increasing
-            start += 64 / no0(width) / 2;
-            if (width <= 4) {
-                hasZeroByte = has_zero_element<width>(v | 0xffff000000000000ULL);
-                if (eq ? !hasZeroByte : (v & 0x0000ffffffffffffULL) == 0) {
-                    // 000?
-                    start += 64 / no0(width) / 4;
-                }
-            }
-        }
-        else {
-            if (width <= 4) {
-                // ??00
-                hasZeroByte = has_zero_element<width>(v | 0xffffffffffff0000ULL);
-                if (eq ? !hasZeroByte : (v & 0x000000000000ffffULL) == 0) {
-                    // 0?00
-                    start += 64 / no0(width) / 4;
-                }
-            }
-        }
-    }
-
-    uint64_t mask =
-        (width == 64
-             ? ~0ULL
-             : ((1ULL << (width == 64 ? 0 : width)) - 1ULL)); // Warning free way of computing (1ULL << width) - 1
-    while (eq == (((v >> (width * start)) & mask) != 0)) {
-        start++;
-    }
-
-    return start;
-}
-
-} // namespace
-
-
 int64_t Array::sum(size_t start, size_t end) const
 {
     REALM_TEMPEX(return sum, m_width, (start, end));
diff --git a/src/realm/array_with_find.hpp b/src/realm/array_with_find.hpp
index e94519ce0a0..ec811a7b977 100644
--- a/src/realm/array_with_find.hpp
+++ b/src/realm/array_with_find.hpp
@@ -58,12 +58,36 @@ Searching: The main finding function is:
 
 namespace realm {
 
+namespace {
 template <class T>
-inline T no0(T v)
+inline constexpr T no0(T v)
 {
     return v == 0 ? 1 : v;
 }
 
+template <size_t width>
+inline constexpr uint64_t lower_bits()
+{
+    if (width == 1)
+        return 0xFFFFFFFFFFFFFFFFULL;
+    else if (width == 2)
+        return 0x5555555555555555ULL;
+    else if (width == 4)
+        return 0x1111111111111111ULL;
+    else if (width == 8)
+        return 0x0101010101010101ULL;
+    else if (width == 16)
+        return 0x0001000100010001ULL;
+    else if (width == 32)
+        return 0x0000000100000001ULL;
+    else if (width == 64)
+        return 0x0000000000000001ULL;
+    else {
+        return uint64_t(-1);
+    }
+}
+} // namespace
+
 class ArrayWithFind {
 public:
     ArrayWithFind(const Array& array) noexcept
@@ -133,9 +157,6 @@ class ArrayWithFind {
     int64_t
     find_gtlt_magic(int64_t v) const; // Compute magic constant needed for searching for value 'v' using bit hacks
 
-    template <size_t width>
-    inline int64_t lower_bits() const; // Return chunk with lower bit set in each element
-
     size_t first_set_bit(uint32_t v) const;
     size_t first_set_bit64(int64_t v) const;
 
@@ -419,36 +440,13 @@ bool ArrayWithFind::find_optimized(int64_t value, size_t start, size_t end, size
 #endif
 }
 
-template <size_t width>
-inline int64_t ArrayWithFind::lower_bits() const
-{
-    if (width == 1)
-        return 0xFFFFFFFFFFFFFFFFULL;
-    else if (width == 2)
-        return 0x5555555555555555ULL;
-    else if (width == 4)
-        return 0x1111111111111111ULL;
-    else if (width == 8)
-        return 0x0101010101010101ULL;
-    else if (width == 16)
-        return 0x0001000100010001ULL;
-    else if (width == 32)
-        return 0x0000000100000001ULL;
-    else if (width == 64)
-        return 0x0000000000000001ULL;
-    else {
-        REALM_ASSERT_DEBUG(false);
-        return int64_t(-1);
-    }
-}
-
 // Tests if any chunk in 'value' is 0
 template <size_t width>
 inline bool ArrayWithFind::test_zero(uint64_t value) const
 {
     uint64_t hasZeroByte;
-    uint64_t lower = lower_bits<width>();
-    uint64_t upper = lower_bits<width>() * 1ULL << (width == 0 ? 0 : (width - 1ULL));
+    constexpr uint64_t lower = lower_bits<width>();
+    constexpr uint64_t upper = lower_bits<width>() * 1ULL << (width == 0 ? 0 : (width - 1ULL));
     hasZeroByte = (value - lower) & ~value & upper;
     return hasZeroByte != 0;
 }
@@ -804,7 +802,7 @@ REALM_FORCEINLINE bool ArrayWithFind::find_sse_intern(__m128i* action_data, __m1
         size_t s = i * sizeof(__m128i) * 8 / no0(width);
 
         while (resmask != 0) {
-            uint64_t upper = lower_bits<width / 8>() << (no0(width / 8) - 1);
+            constexpr uint64_t upper = lower_bits<width / 8>() << (no0(width / 8) - 1);
             uint64_t pattern =
                 resmask &
                 upper; // fixme, bits at wrong offsets. Only OK because we only use them in 'count' aggregate
diff --git a/src/realm/query_engine.hpp b/src/realm/query_engine.hpp
index 998132eeea5..0bf2fe4d5c2 100644
--- a/src/realm/query_engine.hpp
+++ b/src/realm/query_engine.hpp
@@ -76,7 +76,6 @@ TConditionValue:    Type of values in condition column. That is, int64_t, float,
 #include <realm/array_key.hpp>
 #include <realm/array_string.hpp>
 #include <realm/array_binary.hpp>
-#include <realm/array_integer_tpl.hpp>
 #include <realm/array_timestamp.hpp>
 #include <realm/array_decimal128.hpp>
 #include <realm/array_fixed_bytes.hpp>