Implement protocol::Array as std::vector typedefs.

Instead of a custom collection in Array_h.template,
protocol::Array<Foo> shall be std::vector<std::unique_ptr<Foo>>
if Foo is some domain specific protocol type, and
std::vector<Foo> otherwise (for int,double,bool and String).

This requires large scale but mechanical changes as I'm rolling
this. It will not change behavior, but improves performance
in some cases because there's less copying. E.g., the custom
collection is naive and will copy a string on every array access
with protocol::Array::get(i), whereas std::vector<string>[i]
returns a reference.

V8 Roll is here:
https://chromium-review.googlesource.com/c/v8/v8/+/1654091

Chromium Roll is here (still in progress):
https://chromium-review.googlesource.com/c/chromium/src/+/1657628

Change-Id: Ia5ce1f131d133a57f75d349c299270f68f716de0
diff --git a/code_generator.py b/code_generator.py
index b6e447d..9382f01 100755
--- a/code_generator.py
+++ b/code_generator.py
@@ -636,7 +636,6 @@
             "Object_h.template",
             "ValueConversions_h.template",
             "Maybe_h.template",
-            "Array_h.template",
             "DispatcherBase_h.template",
             "Parser_h.template",
             "encoding_h.template",
diff --git a/inspector_protocol.gni b/inspector_protocol.gni
index d612fb6..3e93452 100644
--- a/inspector_protocol.gni
+++ b/inspector_protocol.gni
@@ -36,7 +36,6 @@
       "$inspector_protocol_dir/lib/encoding_h.template",
       "$inspector_protocol_dir/lib/encoding_cpp.template",
       "$inspector_protocol_dir/lib/Allocator_h.template",
-      "$inspector_protocol_dir/lib/Array_h.template",
       "$inspector_protocol_dir/lib/DispatcherBase_cpp.template",
       "$inspector_protocol_dir/lib/DispatcherBase_h.template",
       "$inspector_protocol_dir/lib/ErrorSupport_cpp.template",
diff --git a/inspector_protocol.gypi b/inspector_protocol.gypi
index d614474..c11386d 100644
--- a/inspector_protocol.gypi
+++ b/inspector_protocol.gypi
@@ -8,7 +8,6 @@
       'lib/encoding_h.template',
       'lib/encoding_cpp.template',
       'lib/Allocator_h.template',
-      'lib/Array_h.template',
       'lib/DispatcherBase_cpp.template',
       'lib/DispatcherBase_h.template',
       'lib/ErrorSupport_cpp.template',
diff --git a/lib/Array_h.template b/lib/Array_h.template
deleted file mode 100644
index c420a0f..0000000
--- a/lib/Array_h.template
+++ /dev/null
@@ -1,138 +0,0 @@
-// This file is generated by Array_h.template.
-
-// Copyright 2016 The Chromium 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 {{"_".join(config.protocol.namespace)}}_Array_h
-#define {{"_".join(config.protocol.namespace)}}_Array_h
-
-//#include "ErrorSupport.h"
-//#include "Forward.h"
-//#include "ValueConversions.h"
-//#include "Values.h"
-
-{% for namespace in config.protocol.namespace %}
-namespace {{namespace}} {
-{% endfor %}
-
-template<typename T>
-class Array {
-public:
-    static std::unique_ptr<Array<T>> create()
-    {
-        return std::unique_ptr<Array<T>>(new Array<T>());
-    }
-
-    static std::unique_ptr<Array<T>> fromValue(protocol::Value* value, ErrorSupport* errors)
-    {
-        protocol::ListValue* array = ListValue::cast(value);
-        if (!array) {
-            errors->addError("array expected");
-            return nullptr;
-        }
-        std::unique_ptr<Array<T>> result(new Array<T>());
-        errors->push();
-        for (size_t i = 0; i < array->size(); ++i) {
-            errors->setName(StringUtil::fromInteger(i));
-            std::unique_ptr<T> item = ValueConversions<T>::fromValue(array->at(i), errors);
-            result->m_vector.push_back(std::move(item));
-        }
-        errors->pop();
-        if (errors->hasErrors())
-            return nullptr;
-        return result;
-    }
-
-    void addItem(std::unique_ptr<T> value)
-    {
-        m_vector.push_back(std::move(value));
-    }
-
-    size_t length()
-    {
-        return m_vector.size();
-    }
-
-    T* get(size_t index)
-    {
-        return m_vector[index].get();
-    }
-
-    std::unique_ptr<protocol::ListValue> toValue()
-    {
-        std::unique_ptr<protocol::ListValue> result = ListValue::create();
-        for (auto& item : m_vector)
-            result->pushValue(ValueConversions<T>::toValue(item));
-        return result;
-    }
-
-private:
-    std::vector<std::unique_ptr<T>> m_vector;
-};
-
-template<typename T>
-class ArrayBase {
-public:
-    static std::unique_ptr<Array<T>> create()
-    {
-        return std::unique_ptr<Array<T>>(new Array<T>());
-    }
-
-    static std::unique_ptr<Array<T>> fromValue(protocol::Value* value, ErrorSupport* errors)
-    {
-        protocol::ListValue* array = ListValue::cast(value);
-        if (!array) {
-            errors->addError("array expected");
-            return nullptr;
-        }
-        errors->push();
-        std::unique_ptr<Array<T>> result(new Array<T>());
-        for (size_t i = 0; i < array->size(); ++i) {
-            errors->setName(StringUtil::fromInteger(i));
-            T item = ValueConversions<T>::fromValue(array->at(i), errors);
-            result->m_vector.push_back(item);
-        }
-        errors->pop();
-        if (errors->hasErrors())
-            return nullptr;
-        return result;
-    }
-
-    void addItem(const T& value)
-    {
-        m_vector.push_back(value);
-    }
-
-    size_t length()
-    {
-        return m_vector.size();
-    }
-
-    T get(size_t index)
-    {
-        return m_vector[index];
-    }
-
-    std::unique_ptr<protocol::ListValue> toValue()
-    {
-        std::unique_ptr<protocol::ListValue> result = ListValue::create();
-        for (auto& item : m_vector)
-            result->pushValue(ValueConversions<T>::toValue(item));
-        return result;
-    }
-
-private:
-    std::vector<T> m_vector;
-};
-
-template<> class Array<String> : public ArrayBase<String> {};
-template<> class Array<int> : public ArrayBase<int> {};
-template<> class Array<double> : public ArrayBase<double> {};
-template<> class Array<bool> : public ArrayBase<bool> {};
-
-{% for namespace in config.protocol.namespace %}
-} // namespace {{namespace}}
-{% endfor %}
-
-#endif // !defined({{"_".join(config.protocol.namespace)}}_Array_h)
diff --git a/lib/Forward_h.template b/lib/Forward_h.template
index 746ba20..a6c4b12 100644
--- a/lib/Forward_h.template
+++ b/lib/Forward_h.template
@@ -22,7 +22,6 @@
 namespace {{namespace}} {
 {% endfor %}
 
-template<typename T> class Array;
 class DictionaryValue;
 class DispatchResponse;
 class ErrorSupport;
@@ -35,6 +34,26 @@
 class UberDispatcher;
 class Value;
 
+namespace detail {
+template <typename T>
+struct ArrayTypedef { typedef std::vector<std::unique_ptr<T>> type; };
+
+template <>
+struct ArrayTypedef<String> { typedef std::vector<String> type; };
+
+template <>
+struct ArrayTypedef<int> { typedef std::vector<int> type; };
+
+template <>
+struct ArrayTypedef<double> { typedef std::vector<double> type; };
+
+template <>
+struct ArrayTypedef<bool> { typedef std::vector<bool> type; };
+}  // namespace detail
+
+template <typename T>
+using Array = typename detail::ArrayTypedef<T>::type;
+
 {% for namespace in config.protocol.namespace %}
 } // namespace {{namespace}}
 {% endfor %}
diff --git a/lib/ValueConversions_h.template b/lib/ValueConversions_h.template
index 2ee5b72..63baf68 100644
--- a/lib/ValueConversions_h.template
+++ b/lib/ValueConversions_h.template
@@ -128,6 +128,72 @@
     }
 };
 
+template<typename T>
+struct ValueConversions<std::vector<std::unique_ptr<T>>> {
+    static std::unique_ptr<std::vector<std::unique_ptr<T>>> fromValue(protocol::Value* value, ErrorSupport* errors) {
+        protocol::ListValue* array = ListValue::cast(value);
+        if (!array) {
+            errors->addError("array expected");
+            return nullptr;
+        }
+        errors->push();
+        std::unique_ptr<std::vector<std::unique_ptr<T>>> result(
+            new std::vector<std::unique_ptr<T>>());
+        result->reserve(array->size());
+        for (size_t i = 0; i < array->size(); ++i) {
+            errors->setName(StringUtil::fromInteger(i));
+            auto item = ValueConversions<T>::fromValue(array->at(i), errors);
+            result->emplace_back(std::move(item));
+        }
+        errors->pop();
+        if (errors->hasErrors())
+            return nullptr;
+        return result;
+    }
+
+    static std::unique_ptr<protocol::ListValue> toValue(std::vector<std::unique_ptr<T>>* v)
+    {
+        std::unique_ptr<protocol::ListValue> result = ListValue::create();
+        result->reserve(v->size());
+        for (auto& item : *v)
+            result->pushValue(ValueConversions<T>::toValue(item.get()));
+        return result;
+    }
+
+};
+
+template<typename T>
+struct ValueConversions<std::vector<T>> {
+    static std::unique_ptr<std::vector<T>> fromValue(protocol::Value* value, ErrorSupport* errors) {
+        protocol::ListValue* array = ListValue::cast(value);
+        if (!array) {
+            errors->addError("array expected");
+            return nullptr;
+        }
+        errors->push();
+        std::unique_ptr<std::vector<T>> result(new std::vector<T>());
+        result->reserve(array->size());
+        for (size_t i = 0; i < array->size(); ++i) {
+            errors->setName(StringUtil::fromInteger(i));
+            auto item = ValueConversions<T>::fromValue(array->at(i), errors);
+            result->emplace_back(std::move(item));
+        }
+        errors->pop();
+        if (errors->hasErrors())
+            return nullptr;
+        return result;
+    }
+
+    static std::unique_ptr<protocol::ListValue> toValue(std::vector<T>* v)
+    {
+        std::unique_ptr<protocol::ListValue> result = ListValue::create();
+        result->reserve(v->size());
+        for (auto& item : *v)
+            result->pushValue(ValueConversions<T>::toValue(item));
+        return result;
+    }
+};
+
 template<>
 struct ValueConversions<Value> {
     static std::unique_ptr<Value> fromValue(protocol::Value* value, ErrorSupport* errors)
diff --git a/lib/Values_h.template b/lib/Values_h.template
index 4a2e58f..4d6fde0 100644
--- a/lib/Values_h.template
+++ b/lib/Values_h.template
@@ -271,6 +271,7 @@
 
     Value* at(size_t index);
     size_t size() const { return m_data.size(); }
+    void reserve(size_t capacity) { m_data.reserve(capacity); }
 
 private:
     ListValue();