• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_ARRAY_TRAITS_STL_H_
6 #define MOJO_PUBLIC_CPP_BINDINGS_ARRAY_TRAITS_STL_H_
7 
8 #include <map>
9 #include <set>
10 #include <vector>
11 
12 #include "mojo/public/cpp/bindings/array_traits.h"
13 
14 namespace mojo {
15 
16 template <typename T>
17 struct ArrayTraits<std::vector<T>> {
18   using Element = T;
19 
20   static bool IsNull(const std::vector<T>& input) {
21     // std::vector<> is always converted to non-null mojom array.
22     return false;
23   }
24 
25   static void SetToNull(std::vector<T>* output) {
26     // std::vector<> doesn't support null state. Set it to empty instead.
27     output->clear();
28   }
29 
30   static size_t GetSize(const std::vector<T>& input) { return input.size(); }
31 
32   static T* GetData(std::vector<T>& input) { return input.data(); }
33 
34   static const T* GetData(const std::vector<T>& input) { return input.data(); }
35 
36   static typename std::vector<T>::reference GetAt(std::vector<T>& input,
37                                                   size_t index) {
38     return input[index];
39   }
40 
41   static typename std::vector<T>::const_reference GetAt(
42       const std::vector<T>& input,
43       size_t index) {
44     return input[index];
45   }
46 
47   static inline bool Resize(std::vector<T>& input, size_t size) {
48     // Instead of calling std::vector<T>::resize() directly, this is a hack to
49     // make compilers happy. Some compilers (e.g., Mac, Android, Linux MSan)
50     // currently don't allow resizing types like
51     // std::vector<std::vector<MoveOnlyType>>.
52     // Because the deserialization code doesn't care about the original contents
53     // of |input|, we discard them directly.
54     //
55     // The "inline" keyword of this method matters. Without it, we have observed
56     // significant perf regression with some tests on Mac. crbug.com/631415
57     if (input.size() != size) {
58       std::vector<T> temp(size);
59       input.swap(temp);
60     }
61 
62     return true;
63   }
64 };
65 
66 // This ArrayTraits specialization is used only for serialization.
67 template <typename T>
68 struct ArrayTraits<std::set<T>> {
69   using Element = T;
70   using ConstIterator = typename std::set<T>::const_iterator;
71 
72   static bool IsNull(const std::set<T>& input) {
73     // std::set<> is always converted to non-null mojom array.
74     return false;
75   }
76 
77   static size_t GetSize(const std::set<T>& input) { return input.size(); }
78 
79   static ConstIterator GetBegin(const std::set<T>& input) {
80     return input.begin();
81   }
82   static void AdvanceIterator(ConstIterator& iterator) {
83     ++iterator;
84   }
85   static const T& GetValue(ConstIterator& iterator) {
86     return *iterator;
87   }
88 };
89 
90 template <typename K, typename V>
91 struct MapValuesArrayView {
92   explicit MapValuesArrayView(const std::map<K, V>& map) : map(map) {}
93   const std::map<K, V>& map;
94 };
95 
96 // Convenience function to create a MapValuesArrayView<> that infers the
97 // template arguments from its argument type.
98 template <typename K, typename V>
99 MapValuesArrayView<K, V> MapValuesToArray(const std::map<K, V>& map) {
100   return MapValuesArrayView<K, V>(map);
101 }
102 
103 // This ArrayTraits specialization is used only for serialization and converts
104 // a map<K, V> into an array<V>, discarding the keys.
105 template <typename K, typename V>
106 struct ArrayTraits<MapValuesArrayView<K, V>> {
107   using Element = V;
108   using ConstIterator = typename std::map<K, V>::const_iterator;
109 
110   static bool IsNull(const MapValuesArrayView<K, V>& input) {
111     // std::map<> is always converted to non-null mojom array.
112     return false;
113   }
114 
115   static size_t GetSize(const MapValuesArrayView<K, V>& input) {
116     return input.map.size();
117   }
118   static ConstIterator GetBegin(const MapValuesArrayView<K, V>& input) {
119     return input.map.begin();
120   }
121   static void AdvanceIterator(ConstIterator& iterator) { ++iterator; }
122   static const V& GetValue(ConstIterator& iterator) { return iterator->second; }
123 };
124 
125 }  // namespace mojo
126 
127 #endif  // MOJO_PUBLIC_CPP_BINDINGS_ARRAY_TRAITS_STL_H_
128