Home | History | Annotate | Download | only in bindings
      1 // Copyright 2013 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_H_
      6 #define MOJO_PUBLIC_CPP_BINDINGS_ARRAY_H_
      7 
      8 #include <string.h>
      9 
     10 #include <algorithm>
     11 #include <string>
     12 #include <vector>
     13 
     14 #include "mojo/public/cpp/bindings/lib/array_internal.h"
     15 #include "mojo/public/cpp/bindings/lib/template_util.h"
     16 #include "mojo/public/cpp/bindings/type_converter.h"
     17 
     18 namespace mojo {
     19 
     20 // Provides read-only access to array data.
     21 template <typename T>
     22 class Array {
     23   MOJO_MOVE_ONLY_TYPE_FOR_CPP_03(Array, RValue)
     24  public:
     25   typedef internal::ArrayTraits<T, internal::IsMoveOnlyType<T>::value>
     26       Traits;
     27   typedef typename Traits::ConstRefType ConstRefType;
     28   typedef typename Traits::RefType RefType;
     29   typedef typename Traits::StorageType StorageType;
     30   typedef typename Traits::ForwardType ForwardType;
     31 
     32   typedef internal::Array_Data<typename internal::WrapperTraits<T>::DataType>
     33       Data_;
     34 
     35   Array() : is_null_(true) {}
     36   explicit Array(size_t size) : vec_(size), is_null_(false) {
     37     Traits::Initialize(&vec_);
     38   }
     39   ~Array() { Traits::Finalize(&vec_); }
     40 
     41   Array(RValue other) : is_null_(true) { Take(other.object); }
     42   Array& operator=(RValue other) {
     43     Take(other.object);
     44     return *this;
     45   }
     46 
     47   static Array New(size_t size) {
     48     return Array(size).Pass();
     49   }
     50 
     51   template <typename U>
     52   static Array From(const U& other) {
     53     return TypeConverter<Array, U>::Convert(other);
     54   }
     55 
     56   template <typename U>
     57   U To() const {
     58     return TypeConverter<U, Array>::Convert(*this);
     59   }
     60 
     61   void reset() {
     62     if (!vec_.empty()) {
     63       Traits::Finalize(&vec_);
     64       vec_.clear();
     65     }
     66     is_null_ = true;
     67   }
     68 
     69   bool is_null() const { return is_null_; }
     70 
     71   ConstRefType front() const { return vec_.front(); }
     72   RefType front() { return vec_.front(); }
     73 
     74   size_t size() const { return vec_.size(); }
     75 
     76   ConstRefType at(size_t offset) const { return Traits::at(&vec_, offset); }
     77   ConstRefType operator[](size_t offset) const { return at(offset); }
     78 
     79   RefType at(size_t offset) { return Traits::at(&vec_, offset); }
     80   RefType operator[](size_t offset) { return at(offset); }
     81 
     82   void push_back(ForwardType value) {
     83     is_null_ = false;
     84     Traits::PushBack(&vec_, value);
     85   }
     86 
     87   void resize(size_t size) {
     88     is_null_ = false;
     89     Traits::Resize(&vec_, size);
     90   }
     91 
     92   const std::vector<StorageType>& storage() const {
     93     return vec_;
     94   }
     95   operator const std::vector<StorageType>&() const {
     96     return vec_;
     97   }
     98 
     99   void Swap(Array* other) {
    100     std::swap(is_null_, other->is_null_);
    101     vec_.swap(other->vec_);
    102   }
    103   void Swap(std::vector<StorageType>* other) {
    104     is_null_ = false;
    105     vec_.swap(*other);
    106   }
    107 
    108  private:
    109   typedef std::vector<StorageType> Array::*Testable;
    110 
    111  public:
    112   operator Testable() const { return is_null_ ? 0 : &Array::vec_; }
    113 
    114  private:
    115   void Take(Array* other) {
    116     reset();
    117     Swap(other);
    118   }
    119 
    120   std::vector<StorageType> vec_;
    121   bool is_null_;
    122 };
    123 
    124 template <typename T, typename E>
    125 struct TypeConverter<Array<T>, std::vector<E> > {
    126   static Array<T> Convert(const std::vector<E>& input) {
    127     Array<T> result(input.size());
    128     for (size_t i = 0; i < input.size(); ++i)
    129       result[i] = TypeConverter<T, E>::Convert(input[i]);
    130     return result.Pass();
    131   }
    132 };
    133 
    134 template <typename E, typename T>
    135 struct TypeConverter<std::vector<E>, Array<T> > {
    136   static std::vector<E> Convert(const Array<T>& input) {
    137     std::vector<E> result;
    138     if (!input.is_null()) {
    139       result.resize(input.size());
    140       for (size_t i = 0; i < input.size(); ++i)
    141         result[i] = TypeConverter<E, T>::Convert(input[i]);
    142     }
    143     return result;
    144   }
    145 };
    146 
    147 }  // namespace mojo
    148 
    149 #endif  // MOJO_PUBLIC_CPP_BINDINGS_ARRAY_H_
    150