Home | History | Annotate | Download | only in bindings
      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