Templatize the TypedData wrapper classes

Change-Id: Icedb004338e390205fa6219ee18649ec3cc8febe
diff --git a/typed_data/BUILD.gn b/typed_data/BUILD.gn
index 496bdbf..e456cf4 100644
--- a/typed_data/BUILD.gn
+++ b/typed_data/BUILD.gn
@@ -10,16 +10,15 @@
   sources = [
     "dart_byte_data.cc",
     "dart_byte_data.h",
-    "float32_list.cc",
+    "typed_list.cc",
+    "typed_list.h",
+
+    # Deprecated.
     "float32_list.h",
-    "float64_list.cc",
     "float64_list.h",
-    "int32_list.cc",
     "int32_list.h",
-    "uint8_list.cc",
-    "uint8_list.h",
-    "uint16_list.cc",
     "uint16_list.h",
+    "uint8_list.h",
   ]
 
   deps = [
diff --git a/typed_data/float32_list.cc b/typed_data/float32_list.cc
deleted file mode 100644
index 89d6c12..0000000
--- a/typed_data/float32_list.cc
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2015 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "tonic/typed_data/float32_list.h"
-
-#include "tonic/logging/dart_error.h"
-
-namespace tonic {
-
-Float32List::Float32List()
-    : data_(nullptr), num_elements_(0), dart_handle_(nullptr) {}
-
-Float32List::Float32List(Dart_Handle list)
-    : data_(nullptr), num_elements_(0), dart_handle_(list) {
-  if (Dart_IsNull(list))
-    return;
-
-  Dart_TypedData_Type type;
-  Dart_TypedDataAcquireData(list, &type, reinterpret_cast<void**>(&data_),
-                            &num_elements_);
-  TONIC_DCHECK(!LogIfError(list));
-  if (type != Dart_TypedData_kFloat32)
-    Dart_ThrowException(ToDart("Non-genuine Float32List passed to engine."));
-}
-
-Float32List::Float32List(Float32List&& other)
-    : data_(other.data_),
-      num_elements_(other.num_elements_),
-      dart_handle_(other.dart_handle_) {
-  other.data_ = nullptr;
-  other.dart_handle_ = nullptr;
-}
-
-Float32List::~Float32List() {
-  Release();
-}
-
-void Float32List::Release() {
-  if (data_) {
-    Dart_TypedDataReleaseData(dart_handle_);
-    data_ = nullptr;
-    num_elements_ = 0;
-    dart_handle_ = nullptr;
-  }
-}
-
-Float32List DartConverter<Float32List>::FromArguments(Dart_NativeArguments args,
-                                                      int index,
-                                                      Dart_Handle& exception) {
-  Dart_Handle list = Dart_GetNativeArgument(args, index);
-  TONIC_DCHECK(!LogIfError(list));
-  return Float32List(list);
-}
-
-void DartConverter<Float32List>::SetReturnValue(Dart_NativeArguments args,
-                                                Float32List val) {
-  Dart_SetReturnValue(args, val.dart_handle());
-}
-
-}  // namespace tonic
diff --git a/typed_data/float32_list.h b/typed_data/float32_list.h
index 7976d84..fe2d60d 100644
--- a/typed_data/float32_list.h
+++ b/typed_data/float32_list.h
@@ -5,57 +5,8 @@
 #ifndef LIB_TONIC_TYPED_DATA_FLOAT32_LIST_H_
 #define LIB_TONIC_TYPED_DATA_FLOAT32_LIST_H_
 
-#include "third_party/dart/runtime/include/dart_api.h"
-#include "tonic/converter/dart_converter.h"
+#warning float32_list.h is deprecated; use typed_list.h instead.
 
-namespace tonic {
-
-// A simple wrapper around a Dart Float32List. It uses Dart_TypedDataAcquireData
-// to obtain a raw pointer to the data, which is released when this object is
-// destroyed.
-//
-// This is designed to be used with DartConverter only.
-class Float32List {
- public:
-  explicit Float32List(Dart_Handle list);
-  Float32List(Float32List&& other);
-  Float32List();
-  ~Float32List();
-
-  float& at(intptr_t i) {
-    TONIC_CHECK(i < num_elements_);
-    return data_[i];
-  }
-  const float& at(intptr_t i) const {
-    TONIC_CHECK(i < num_elements_);
-    return data_[i];
-  }
-
-  float& operator[](intptr_t i) { return at(i); }
-  const float& operator[](intptr_t i) const { return at(i); }
-
-  const float* data() const { return data_; }
-  intptr_t num_elements() const { return num_elements_; }
-  Dart_Handle dart_handle() const { return dart_handle_; }
-
-  void Release();
-
- private:
-  float* data_;
-  intptr_t num_elements_;
-  Dart_Handle dart_handle_;
-
-  Float32List(const Float32List& other) = delete;
-};
-
-template <>
-struct DartConverter<Float32List> {
-  static void SetReturnValue(Dart_NativeArguments args, Float32List val);
-  static Float32List FromArguments(Dart_NativeArguments args,
-                                   int index,
-                                   Dart_Handle& exception);
-};
-
-}  // namespace tonic
+#include "tonic/typed_data/typed_list.h"
 
 #endif  // LIB_TONIC_TYPED_DATA_FLOAT32_LIST_H_
diff --git a/typed_data/float64_list.cc b/typed_data/float64_list.cc
deleted file mode 100644
index 18768ee..0000000
--- a/typed_data/float64_list.cc
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2015 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "tonic/typed_data/float64_list.h"
-
-#include "tonic/logging/dart_error.h"
-
-namespace tonic {
-
-Float64List::Float64List()
-    : data_(nullptr), num_elements_(0), dart_handle_(nullptr) {}
-
-Float64List::Float64List(Dart_Handle list)
-    : data_(nullptr), num_elements_(0), dart_handle_(list) {
-  if (Dart_IsNull(list))
-    return;
-
-  Dart_TypedData_Type type;
-  Dart_TypedDataAcquireData(list, &type, reinterpret_cast<void**>(&data_),
-                            &num_elements_);
-  TONIC_DCHECK(!LogIfError(list));
-  if (type != Dart_TypedData_kFloat64)
-    Dart_ThrowException(ToDart("Non-genuine Float64List passed to engine."));
-}
-
-Float64List::Float64List(Float64List&& other)
-    : data_(other.data_),
-      num_elements_(other.num_elements_),
-      dart_handle_(other.dart_handle_) {
-  other.data_ = nullptr;
-  other.dart_handle_ = nullptr;
-}
-
-Float64List::~Float64List() {
-  Release();
-}
-
-void Float64List::Release() {
-  if (data_) {
-    Dart_TypedDataReleaseData(dart_handle_);
-    data_ = nullptr;
-    num_elements_ = 0;
-    dart_handle_ = nullptr;
-  }
-}
-
-Float64List DartConverter<Float64List>::FromArguments(Dart_NativeArguments args,
-                                                      int index,
-                                                      Dart_Handle& exception) {
-  Dart_Handle list = Dart_GetNativeArgument(args, index);
-  TONIC_DCHECK(!LogIfError(list));
-  return Float64List(list);
-}
-
-void DartConverter<Float64List>::SetReturnValue(Dart_NativeArguments args,
-                                                Float64List val) {
-  Dart_SetReturnValue(args, val.dart_handle());
-}
-
-}  // namespace tonic
diff --git a/typed_data/float64_list.h b/typed_data/float64_list.h
index c3ad99f..0a329e3 100644
--- a/typed_data/float64_list.h
+++ b/typed_data/float64_list.h
@@ -5,57 +5,8 @@
 #ifndef LIB_TONIC_TYPED_DATA_FLOAT64_LIST_H_
 #define LIB_TONIC_TYPED_DATA_FLOAT64_LIST_H_
 
-#include "third_party/dart/runtime/include/dart_api.h"
-#include "tonic/converter/dart_converter.h"
+#warning float64_list.h is deprecated; use typed_list.h instead.
 
-namespace tonic {
-
-// A simple wrapper around a Dart Float64List. It uses Dart_TypedDataAcquireData
-// to obtain a raw pointer to the data, which is released when this object is
-// destroyed.
-//
-// This is designed to be used with DartConverter only.
-class Float64List {
- public:
-  explicit Float64List(Dart_Handle list);
-  Float64List(Float64List&& other);
-  Float64List();
-  ~Float64List();
-
-  double& at(intptr_t i) {
-    TONIC_CHECK(i < num_elements_);
-    return data_[i];
-  }
-  const double& at(intptr_t i) const {
-    TONIC_CHECK(i < num_elements_);
-    return data_[i];
-  }
-
-  double& operator[](intptr_t i) { return at(i); }
-  const double& operator[](intptr_t i) const { return at(i); }
-
-  const double* data() const { return data_; }
-  intptr_t num_elements() const { return num_elements_; }
-  Dart_Handle dart_handle() const { return dart_handle_; }
-
-  void Release();
-
- private:
-  double* data_;
-  intptr_t num_elements_;
-  Dart_Handle dart_handle_;
-
-  Float64List(const Float64List& other) = delete;
-};
-
-template <>
-struct DartConverter<Float64List> {
-  static void SetReturnValue(Dart_NativeArguments args, Float64List val);
-  static Float64List FromArguments(Dart_NativeArguments args,
-                                   int index,
-                                   Dart_Handle& exception);
-};
-
-}  // namespace tonic
+#include "tonic/typed_data/typed_list.h"
 
 #endif  // LIB_TONIC_TYPED_DATA_FLOAT64_LIST_H_
diff --git a/typed_data/int32_list.cc b/typed_data/int32_list.cc
deleted file mode 100644
index abfe2f6..0000000
--- a/typed_data/int32_list.cc
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2015 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "tonic/typed_data/int32_list.h"
-
-#include "tonic/logging/dart_error.h"
-
-namespace tonic {
-
-Int32List::Int32List()
-    : data_(nullptr), num_elements_(0), dart_handle_(nullptr) {}
-
-Int32List::Int32List(Dart_Handle list)
-    : data_(nullptr), num_elements_(0), dart_handle_(list) {
-  if (Dart_IsNull(list))
-    return;
-
-  Dart_TypedData_Type type;
-  Dart_TypedDataAcquireData(list, &type, reinterpret_cast<void**>(&data_),
-                            &num_elements_);
-  TONIC_DCHECK(!LogIfError(list));
-  if (type != Dart_TypedData_kInt32)
-    Dart_ThrowException(ToDart("Non-genuine Int32List passed to engine."));
-}
-
-Int32List::Int32List(Int32List&& other)
-    : data_(other.data_),
-      num_elements_(other.num_elements_),
-      dart_handle_(other.dart_handle_) {
-  other.data_ = nullptr;
-  other.dart_handle_ = nullptr;
-}
-
-Int32List::~Int32List() {
-  Release();
-}
-
-void Int32List::Release() {
-  if (data_) {
-    Dart_TypedDataReleaseData(dart_handle_);
-    data_ = nullptr;
-    num_elements_ = 0;
-    dart_handle_ = nullptr;
-  }
-}
-
-Int32List DartConverter<Int32List>::FromArguments(Dart_NativeArguments args,
-                                                  int index,
-                                                  Dart_Handle& exception) {
-  Dart_Handle list = Dart_GetNativeArgument(args, index);
-  TONIC_DCHECK(!LogIfError(list));
-  return Int32List(list);
-}
-
-void DartConverter<Int32List>::SetReturnValue(Dart_NativeArguments args,
-                                              Int32List val) {
-  Dart_SetReturnValue(args, val.dart_handle());
-}
-
-}  // namespace tonic
diff --git a/typed_data/int32_list.h b/typed_data/int32_list.h
index a8876ce..8c31520 100644
--- a/typed_data/int32_list.h
+++ b/typed_data/int32_list.h
@@ -5,57 +5,8 @@
 #ifndef LIB_TONIC_TYPED_DATA_INT32_LIST_H_
 #define LIB_TONIC_TYPED_DATA_INT32_LIST_H_
 
-#include "third_party/dart/runtime/include/dart_api.h"
-#include "tonic/converter/dart_converter.h"
+#warning int32_list.h is deprecated; use typed_list.h instead.
 
-namespace tonic {
-
-// A simple wrapper around a Dart Int32List. It uses Dart_TypedDataAcquireData
-// to obtain a raw pointer to the data, which is released when this object is
-// destroyed.
-//
-// This is designed to be used with DartConverter only.
-class Int32List {
- public:
-  explicit Int32List(Dart_Handle list);
-  Int32List(Int32List&& other);
-  Int32List();
-  ~Int32List();
-
-  int32_t& at(intptr_t i) {
-    TONIC_CHECK(i < num_elements_);
-    return data_[i];
-  }
-  const int32_t& at(intptr_t i) const {
-    TONIC_CHECK(i < num_elements_);
-    return data_[i];
-  }
-
-  int32_t& operator[](intptr_t i) { return at(i); }
-  const int32_t& operator[](intptr_t i) const { return at(i); }
-
-  const int32_t* data() const { return data_; }
-  intptr_t num_elements() const { return num_elements_; }
-  Dart_Handle dart_handle() const { return dart_handle_; }
-
-  void Release();
-
- private:
-  int32_t* data_;
-  intptr_t num_elements_;
-  Dart_Handle dart_handle_;
-
-  Int32List(const Int32List& other) = delete;
-};
-
-template <>
-struct DartConverter<Int32List> {
-  static void SetReturnValue(Dart_NativeArguments args, Int32List val);
-  static Int32List FromArguments(Dart_NativeArguments args,
-                                 int index,
-                                 Dart_Handle& exception);
-};
-
-}  // namespace tonic
+#include "tonic/typed_data/typed_list.h"
 
 #endif  // LIB_TONIC_TYPED_DATA_INT32_LIST_H_
diff --git a/typed_data/typed_list.cc b/typed_data/typed_list.cc
new file mode 100644
index 0000000..91786c2
--- /dev/null
+++ b/typed_data/typed_list.cc
@@ -0,0 +1,104 @@
+// Copyright 2019 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "tonic/typed_data/typed_list.h"
+
+#include <cstring>
+
+#include "tonic/logging/dart_error.h"
+
+namespace tonic {
+
+template <Dart_TypedData_Type kTypeName, typename ElemType>
+TypedList<kTypeName, ElemType>::TypedList()
+    : data_(nullptr), num_elements_(0), dart_handle_(nullptr) {}
+
+template <Dart_TypedData_Type kTypeName, typename ElemType>
+TypedList<kTypeName, ElemType>::TypedList(Dart_Handle list)
+    : data_(nullptr), num_elements_(0), dart_handle_(list) {
+  if (Dart_IsNull(list))
+    return;
+
+  Dart_TypedData_Type type;
+  Dart_TypedDataAcquireData(list, &type, reinterpret_cast<void**>(&data_),
+                            &num_elements_);
+  TONIC_DCHECK(!LogIfError(list));
+  if (type != kTypeName)
+    Dart_ThrowException(ToDart("Non-genuine TypedData passed to engine."));
+}
+
+template <Dart_TypedData_Type kTypeName, typename ElemType>
+TypedList<kTypeName, ElemType>::TypedList(
+    TypedList<kTypeName, ElemType>&& other)
+    : data_(other.data_),
+      num_elements_(other.num_elements_),
+      dart_handle_(other.dart_handle_) {
+  other.data_ = nullptr;
+  other.num_elements_ = 0;
+  other.dart_handle_ = nullptr;
+}
+
+template <Dart_TypedData_Type kTypeName, typename ElemType>
+TypedList<kTypeName, ElemType>::~TypedList() {
+  Release();
+}
+
+template <Dart_TypedData_Type kTypeName, typename ElemType>
+void TypedList<kTypeName, ElemType>::Release() {
+  if (data_) {
+    Dart_TypedDataReleaseData(dart_handle_);
+    data_ = nullptr;
+    num_elements_ = 0;
+    dart_handle_ = nullptr;
+  }
+}
+
+template <Dart_TypedData_Type kTypeName, typename ElemType>
+TypedList<kTypeName, ElemType>
+DartConverter<TypedList<kTypeName, ElemType>>::FromArguments(
+    Dart_NativeArguments args,
+    int index,
+    Dart_Handle& exception) {
+  Dart_Handle list = Dart_GetNativeArgument(args, index);
+  TONIC_DCHECK(!LogIfError(list));
+  return TypedList<kTypeName, ElemType>(list);
+}
+
+template <Dart_TypedData_Type kTypeName, typename ElemType>
+void DartConverter<TypedList<kTypeName, ElemType>>::SetReturnValue(
+    Dart_NativeArguments args,
+    TypedList<kTypeName, ElemType> val) {
+  Dart_SetReturnValue(args, val.dart_handle());
+}
+
+template <Dart_TypedData_Type kTypeName, typename ElemType>
+Dart_Handle DartConverter<TypedList<kTypeName, ElemType>>::ToDart(
+    const ElemType* buffer,
+    unsigned int length) {
+  const intptr_t buffer_length = static_cast<intptr_t>(length);
+  Dart_Handle array = Dart_NewTypedData(kTypeName, buffer_length);
+  TONIC_DCHECK(!LogIfError(array));
+  {
+    Dart_TypedData_Type type;
+    void* data = nullptr;
+    intptr_t data_length = 0;
+    Dart_TypedDataAcquireData(array, &type, &data, &data_length);
+    TONIC_CHECK(type == kTypeName);
+    TONIC_CHECK(data);
+    TONIC_CHECK(data_length == buffer_length);
+    std::memmove(data, buffer, data_length * sizeof(ElemType));
+    Dart_TypedDataReleaseData(array);
+  }
+  return array;
+}
+
+#define TONIC_TYPED_DATA_DEFINE(name, type)               \
+  template class TypedList<Dart_TypedData_k##name, type>; \
+  template struct DartConverter<name##List>;
+
+TONIC_TYPED_DATA_FOREACH(TONIC_TYPED_DATA_DEFINE)
+
+#undef TONIC_TYPED_DATA_DEFINE
+
+}  // namespace tonic
diff --git a/typed_data/typed_list.h b/typed_data/typed_list.h
new file mode 100644
index 0000000..f52bbcb
--- /dev/null
+++ b/typed_data/typed_list.h
@@ -0,0 +1,85 @@
+// Copyright 2016 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef LIB_TONIC_TYPED_DATA_TYPED_LIST_H_
+#define LIB_TONIC_TYPED_DATA_TYPED_LIST_H_
+
+#include "third_party/dart/runtime/include/dart_api.h"
+#include "tonic/converter/dart_converter.h"
+
+namespace tonic {
+
+// A simple wrapper around Dart TypedData objects. It uses
+// Dart_TypedDataAcquireData to obtain a raw pointer to the data, which is
+// released when this object is destroyed.
+//
+// This is designed to be used with DartConverter only.
+template <Dart_TypedData_Type kTypeName, typename ElemType>
+class TypedList {
+ public:
+  explicit TypedList(Dart_Handle list);
+  TypedList(TypedList<kTypeName, ElemType>&& other);
+  TypedList();
+  ~TypedList();
+
+  ElemType& at(intptr_t i) {
+    TONIC_CHECK(0 <= i);
+    TONIC_CHECK(i < num_elements_);
+    return data_[i];
+  }
+  const ElemType& at(intptr_t i) const {
+    TONIC_CHECK(0 <= i);
+    TONIC_CHECK(i < num_elements_);
+    return data_[i];
+  }
+
+  ElemType& operator[](intptr_t i) { return at(i); }
+  const ElemType& operator[](intptr_t i) const { return at(i); }
+
+  const ElemType* data() const { return data_; }
+  intptr_t num_elements() const { return num_elements_; }
+  Dart_Handle dart_handle() const { return dart_handle_; }
+
+  void Release();
+
+ private:
+  ElemType* data_;
+  intptr_t num_elements_;
+  Dart_Handle dart_handle_;
+};
+
+template <Dart_TypedData_Type kTypeName, typename ElemType>
+struct DartConverter<TypedList<kTypeName, ElemType>> {
+  static void SetReturnValue(Dart_NativeArguments args,
+                             TypedList<kTypeName, ElemType> val);
+  static TypedList<kTypeName, ElemType> FromArguments(Dart_NativeArguments args,
+                                                      int index,
+                                                      Dart_Handle& exception);
+  static Dart_Handle ToDart(const ElemType* buffer, unsigned int length);
+};
+
+#define TONIC_TYPED_DATA_FOREACH(F) \
+  F(Int8, int8_t)                   \
+  F(Uint8, uint8_t)                 \
+  F(Int16, int16_t)                 \
+  F(Uint16, uint16_t)               \
+  F(Int32, int32_t)                 \
+  F(Uint32, uint32_t)               \
+  F(Int64, int64_t)                 \
+  F(Uint64, uint64_t)               \
+  F(Float32, float)                 \
+  F(Float64, double)
+
+#define TONIC_TYPED_DATA_DECLARE(name, type)                     \
+  using name##List = TypedList<Dart_TypedData_k##name, type>;    \
+  extern template class TypedList<Dart_TypedData_k##name, type>; \
+  extern template struct DartConverter<name##List>;
+
+TONIC_TYPED_DATA_FOREACH(TONIC_TYPED_DATA_DECLARE)
+
+#undef TONIC_TYPED_DATA_DECLARE
+
+}  // namespace tonic
+
+#endif  // LIB_TONIC_TYPED_DATA_TYPED_LIST_H_
diff --git a/typed_data/uint16_list.cc b/typed_data/uint16_list.cc
deleted file mode 100644
index 8a1f15a..0000000
--- a/typed_data/uint16_list.cc
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright 2015 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "tonic/typed_data/uint16_list.h"
-
-#include <string.h>
-
-#include "tonic/logging/dart_error.h"
-
-namespace tonic {
-
-Uint16List::Uint16List()
-    : data_(nullptr), num_elements_(0), dart_handle_(nullptr) {}
-
-Uint16List::Uint16List(Dart_Handle list)
-    : data_(nullptr), num_elements_(0), dart_handle_(list) {
-  if (Dart_IsNull(list))
-    return;
-
-  Dart_TypedData_Type type;
-  Dart_TypedDataAcquireData(list, &type, reinterpret_cast<void**>(&data_),
-                            &num_elements_);
-  TONIC_DCHECK(!LogIfError(list));
-  if (type != Dart_TypedData_kUint16)
-    Dart_ThrowException(ToDart("Non-genuine Uint16List passed to engine."));
-}
-
-Uint16List::Uint16List(Uint16List&& other)
-    : data_(other.data_),
-      num_elements_(other.num_elements_),
-      dart_handle_(other.dart_handle_) {
-  other.data_ = nullptr;
-  other.dart_handle_ = nullptr;
-}
-
-Uint16List::~Uint16List() {
-  Release();
-}
-
-void Uint16List::Release() {
-  if (data_) {
-    Dart_TypedDataReleaseData(dart_handle_);
-    data_ = nullptr;
-    num_elements_ = 0;
-    dart_handle_ = nullptr;
-  }
-}
-
-Uint16List DartConverter<Uint16List>::FromArguments(Dart_NativeArguments args,
-                                                    int index,
-                                                    Dart_Handle& exception) {
-  Dart_Handle list = Dart_GetNativeArgument(args, index);
-  TONIC_DCHECK(!LogIfError(list));
-  return Uint16List(list);
-}
-
-void DartConverter<Uint16List>::SetReturnValue(Dart_NativeArguments args,
-                                               Uint16List val) {
-  Dart_SetReturnValue(args, val.dart_handle());
-}
-
-Dart_Handle DartConverter<Uint16List>::ToDart(const uint16_t* buffer,
-                                              unsigned int length) {
-  const intptr_t buffer_length = static_cast<intptr_t>(length);
-  Dart_Handle array = Dart_NewTypedData(Dart_TypedData_kUint16, buffer_length);
-  TONIC_DCHECK(!LogIfError(array));
-  {
-    Dart_TypedData_Type type;
-    void* data = nullptr;
-    intptr_t data_length = 0;
-    Dart_TypedDataAcquireData(array, &type, &data, &data_length);
-    TONIC_CHECK(type == Dart_TypedData_kUint16);
-    TONIC_CHECK(data);
-    TONIC_CHECK(data_length == buffer_length);
-    memmove(data, buffer, data_length * sizeof(uint16_t));
-    Dart_TypedDataReleaseData(array);
-  }
-  return array;
-}
-
-}  // namespace tonic
diff --git a/typed_data/uint16_list.h b/typed_data/uint16_list.h
index f606893..708b35f 100644
--- a/typed_data/uint16_list.h
+++ b/typed_data/uint16_list.h
@@ -5,58 +5,8 @@
 #ifndef LIB_TONIC_TYPED_DATA_UINT16_LIST_H_
 #define LIB_TONIC_TYPED_DATA_UINT16_LIST_H_
 
-#include "third_party/dart/runtime/include/dart_api.h"
-#include "tonic/converter/dart_converter.h"
+#warning uint16_list.h is deprecated; use typed_list.h instead.
 
-namespace tonic {
-
-// A simple wrapper around a Dart Uint16List. It uses Dart_TypedDataAcquireData
-// to obtain a raw pointer to the data, which is released when this object is
-// destroyed.
-//
-// This is designed to be used with DartConverter only.
-class Uint16List {
- public:
-  explicit Uint16List(Dart_Handle list);
-  Uint16List(Uint16List&& other);
-  Uint16List();
-  ~Uint16List();
-
-  uint16_t& at(intptr_t i) {
-    TONIC_CHECK(i < num_elements_);
-    return data_[i];
-  }
-  const uint16_t& at(intptr_t i) const {
-    TONIC_CHECK(i < num_elements_);
-    return data_[i];
-  }
-
-  uint16_t& operator[](intptr_t i) { return at(i); }
-  const uint16_t& operator[](intptr_t i) const { return at(i); }
-
-  const uint16_t* data() const { return data_; }
-  intptr_t num_elements() const { return num_elements_; }
-  Dart_Handle dart_handle() const { return dart_handle_; }
-
-  void Release();
-
- private:
-  uint16_t* data_;
-  intptr_t num_elements_;
-  Dart_Handle dart_handle_;
-
-  Uint16List(const Uint16List& other) = delete;
-};
-
-template <>
-struct DartConverter<Uint16List> {
-  static void SetReturnValue(Dart_NativeArguments args, Uint16List val);
-  static Uint16List FromArguments(Dart_NativeArguments args,
-                                 int index,
-                                 Dart_Handle& exception);
-  static Dart_Handle ToDart(const uint16_t* buffer, unsigned int length);
-};
-
-}  // namespace tonic
+#include "tonic/typed_data/typed_list.h"
 
 #endif  // LIB_TONIC_TYPED_DATA_UINT16_LIST_H_
diff --git a/typed_data/uint8_list.cc b/typed_data/uint8_list.cc
deleted file mode 100644
index 8da7660..0000000
--- a/typed_data/uint8_list.cc
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright 2015 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "tonic/typed_data/uint8_list.h"
-
-#include <string.h>
-
-#include "tonic/logging/dart_error.h"
-
-namespace tonic {
-
-Uint8List::Uint8List()
-    : data_(nullptr), num_elements_(0), dart_handle_(nullptr) {}
-
-Uint8List::Uint8List(Dart_Handle list)
-    : data_(nullptr), num_elements_(0), dart_handle_(list) {
-  if (Dart_IsNull(list))
-    return;
-
-  Dart_TypedData_Type type;
-  Dart_TypedDataAcquireData(list, &type, reinterpret_cast<void**>(&data_),
-                            &num_elements_);
-  TONIC_DCHECK(!LogIfError(list));
-  if (type != Dart_TypedData_kUint8)
-    Dart_ThrowException(ToDart("Non-genuine Uint8List passed to engine."));
-}
-
-Uint8List::Uint8List(Uint8List&& other)
-    : data_(other.data_),
-      num_elements_(other.num_elements_),
-      dart_handle_(other.dart_handle_) {
-  other.data_ = nullptr;
-  other.dart_handle_ = nullptr;
-}
-
-Uint8List::~Uint8List() {
-  Release();
-}
-
-void Uint8List::Release() {
-  if (data_) {
-    Dart_TypedDataReleaseData(dart_handle_);
-    data_ = nullptr;
-    num_elements_ = 0;
-    dart_handle_ = nullptr;
-  }
-}
-
-Uint8List DartConverter<Uint8List>::FromArguments(Dart_NativeArguments args,
-                                                  int index,
-                                                  Dart_Handle& exception) {
-  Dart_Handle list = Dart_GetNativeArgument(args, index);
-  TONIC_DCHECK(!LogIfError(list));
-  return Uint8List(list);
-}
-
-void DartConverter<Uint8List>::SetReturnValue(Dart_NativeArguments args,
-                                              Uint8List val) {
-  Dart_SetReturnValue(args, val.dart_handle());
-}
-
-Dart_Handle DartConverter<Uint8List>::ToDart(const uint8_t* buffer,
-                                             unsigned int length) {
-  const intptr_t buffer_length = static_cast<intptr_t>(length);
-  Dart_Handle array = Dart_NewTypedData(Dart_TypedData_kUint8, buffer_length);
-  TONIC_DCHECK(!LogIfError(array));
-  {
-    Dart_TypedData_Type type;
-    void* data = nullptr;
-    intptr_t data_length = 0;
-    Dart_TypedDataAcquireData(array, &type, &data, &data_length);
-    TONIC_CHECK(type == Dart_TypedData_kUint8);
-    TONIC_CHECK(data);
-    TONIC_CHECK(data_length == buffer_length);
-    memmove(data, buffer, data_length);
-    Dart_TypedDataReleaseData(array);
-  }
-  return array;
-}
-
-}  // namespace tonic
diff --git a/typed_data/uint8_list.h b/typed_data/uint8_list.h
index 77bb53c..f99c6a8 100644
--- a/typed_data/uint8_list.h
+++ b/typed_data/uint8_list.h
@@ -5,58 +5,8 @@
 #ifndef LIB_TONIC_TYPED_DATA_UINT8_LIST_H_
 #define LIB_TONIC_TYPED_DATA_UINT8_LIST_H_
 
-#include "third_party/dart/runtime/include/dart_api.h"
-#include "tonic/converter/dart_converter.h"
+#warning uint8_list.h is deprecated; use typed_list.h instead.
 
-namespace tonic {
-
-// A simple wrapper around a Dart Uint8List. It uses Dart_TypedDataAcquireData
-// to obtain a raw pointer to the data, which is released when this object is
-// destroyed.
-//
-// This is designed to be used with DartConverter only.
-class Uint8List {
- public:
-  explicit Uint8List(Dart_Handle list);
-  Uint8List(Uint8List&& other);
-  Uint8List();
-  ~Uint8List();
-
-  uint8_t& at(intptr_t i) {
-    TONIC_CHECK(i < num_elements_);
-    return data_[i];
-  }
-  const uint8_t& at(intptr_t i) const {
-    TONIC_CHECK(i < num_elements_);
-    return data_[i];
-  }
-
-  uint8_t& operator[](intptr_t i) { return at(i); }
-  const uint8_t& operator[](intptr_t i) const { return at(i); }
-
-  const uint8_t* data() const { return data_; }
-  intptr_t num_elements() const { return num_elements_; }
-  Dart_Handle dart_handle() const { return dart_handle_; }
-
-  void Release();
-
- private:
-  uint8_t* data_;
-  intptr_t num_elements_;
-  Dart_Handle dart_handle_;
-
-  Uint8List(const Uint8List& other) = delete;
-};
-
-template <>
-struct DartConverter<Uint8List> {
-  static void SetReturnValue(Dart_NativeArguments args, Uint8List val);
-  static Uint8List FromArguments(Dart_NativeArguments args,
-                                 int index,
-                                 Dart_Handle& exception);
-  static Dart_Handle ToDart(const uint8_t* buffer, unsigned int length);
-};
-
-}  // namespace tonic
+#include "tonic/typed_data/typed_list.h"
 
 #endif  // LIB_TONIC_TYPED_DATA_UINT8_LIST_H_