Remove duplicate forms of spancpy()

Borrow the internal code from span.h that allows making a span<const T>
from a span<T> when appropriate to do so. Then add const to tests to
show that it is accepted.

Change-Id: Idc1d5f07a005f57fcd95433166ab506a3b91a9c3
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/82731
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/core/fxcrt/span_util.h b/core/fxcrt/span_util.h
index bbf5ec5..6d23497 100644
--- a/core/fxcrt/span_util.h
+++ b/core/fxcrt/span_util.h
@@ -5,6 +5,8 @@
 #ifndef CORE_FXCRT_SPAN_UTIL_H_
 #define CORE_FXCRT_SPAN_UTIL_H_
 
+#include <string.h>
+
 #include <vector>
 
 #include "third_party/base/check_op.h"
@@ -12,32 +14,20 @@
 
 namespace fxcrt {
 
-// NOTE: there are separate versions fot span<T> and span<const T>
-// source arguments because type deduction seems to have trouble with
-// automatically converting span<T> to span<const T>.
-
 // Bounds-checked copies from spans into spans.
-template <typename T>
-void spancpy(pdfium::span<T> dst, pdfium::span<const T> src) {
-  CHECK_GE(dst.size(), src.size());
-  memcpy(dst.data(), src.data(), src.size_bytes());
-}
-
-template <typename T>
-void spancpy(pdfium::span<T> dst, pdfium::span<T> src) {
+template <typename T,
+          typename U,
+          typename = pdfium::internal::EnableIfLegalSpanConversion<T, U>>
+void spancpy(pdfium::span<T> dst, pdfium::span<U> src) {
   CHECK_GE(dst.size(), src.size());
   memcpy(dst.data(), src.data(), src.size_bytes());
 }
 
 // Bounds-checked moves from spans into spans.
-template <typename T>
-void spanmove(pdfium::span<T> dst, pdfium::span<T> src) {
-  CHECK_GE(dst.size(), src.size());
-  memmove(dst.data(), src.data(), src.size_bytes());
-}
-
-template <typename T>
-void spanmove(pdfium::span<T> dst, pdfium::span<const T> src) {
+template <typename T,
+          typename U,
+          typename = pdfium::internal::EnableIfLegalSpanConversion<T, U>>
+void spanmove(pdfium::span<T> dst, pdfium::span<U> src) {
   CHECK_GE(dst.size(), src.size());
   memmove(dst.data(), src.data(), src.size_bytes());
 }
diff --git a/core/fxcrt/span_util_unittest.cpp b/core/fxcrt/span_util_unittest.cpp
index d0de999..aae4f43 100644
--- a/core/fxcrt/span_util_unittest.cpp
+++ b/core/fxcrt/span_util_unittest.cpp
@@ -39,7 +39,8 @@
 TEST(Spancpy, FitsWithin) {
   std::vector<char> src(2, 'A');
   std::vector<char> dst(4, 'B');
-  fxcrt::spancpy(fxcrt::Subspan(dst, 1), pdfium::make_span(src));
+  // Also show that a const src argument is acceptable.
+  fxcrt::spancpy(fxcrt::Subspan(dst, 1), pdfium::span<const char>(src));
   EXPECT_EQ(dst[0], 'B');
   EXPECT_EQ(dst[1], 'A');
   EXPECT_EQ(dst[2], 'A');
@@ -65,3 +66,14 @@
   EXPECT_EQ(dst[2], 'B');
   EXPECT_EQ(dst[3], 'B');
 }
+
+TEST(Spanmove, FitsWithin) {
+  std::vector<char> src(2, 'A');
+  std::vector<char> dst(4, 'B');
+  // Also show that a const src argument is acceptable.
+  fxcrt::spanmove(fxcrt::Subspan(dst, 1), pdfium::span<const char>(src));
+  EXPECT_EQ(dst[0], 'B');
+  EXPECT_EQ(dst[1], 'A');
+  EXPECT_EQ(dst[2], 'A');
+  EXPECT_EQ(dst[3], 'B');
+}