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>::ConvertFrom(other);
     54   }
     55 
     56   template <typename U>
     57   U To() const {
     58     return TypeConverter<Array, U>::ConvertTo(*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   size_t size() const { return vec_.size(); }
     72 
     73   ConstRefType at(size_t offset) const { return Traits::at(&vec_, offset); }
     74   ConstRefType operator[](size_t offset) const { return at(offset); }
     75 
     76   RefType at(size_t offset) { return Traits::at(&vec_, offset); }
     77   RefType operator[](size_t offset) { return at(offset); }
     78 
     79   void push_back(ForwardType value) {
     80     is_null_ = false;
     81     Traits::PushBack(&vec_, value);
     82   }
     83 
     84   void resize(size_t size) {
     85     is_null_ = false;
     86     Traits::Resize(&vec_, size);
     87   }
     88 
     89   const std::vector<StorageType>& storage() const {
     90     return vec_;
     91   }
     92   operator const std::vector<StorageType>&() const {
     93     return vec_;
     94   }
     95 
     96   void Swap(Array* other) {
     97     std::swap(is_null_, other->is_null_);
     98     vec_.swap(other->vec_);
     99   }
    100   void Swap(std::vector<StorageType>* other) {
    101     is_null_ = false;
    102     vec_.swap(*other);
    103   }
    104 
    105  private:
    106   typedef std::vector<StorageType> Array::*Testable;
    107 
    108  public:
    109   operator Testable() const { return is_null_ ? 0 : &Array::vec_; }
    110 
    111  private:
    112   void Take(Array* other) {
    113     reset();
    114     Swap(other);
    115   }
    116 
    117   std::vector<StorageType> vec_;
    118   bool is_null_;
    119 };
    120 
    121 template <typename T, typename E>
    122 class TypeConverter<Array<T>, std::vector<E> > {
    123  public:
    124   static Array<T> ConvertFrom(const std::vector<E>& input) {
    125     Array<T> result(input.size());
    126     for (size_t i = 0; i < input.size(); ++i)
    127       result[i] = TypeConverter<T, E>::ConvertFrom(input[i]);
    128     return result.Pass();
    129   }
    130   static std::vector<E> ConvertTo(const Array<T>& input) {
    131     std::vector<E> result;
    132     if (!input.is_null()) {
    133       result.resize(input.size());
    134       for (size_t i = 0; i < input.size(); ++i)
    135         result[i] = TypeConverter<T, E>::ConvertTo(input[i]);
    136     }
    137     return result;
    138   }
    139 };
    140 
    141 }  // namespace mojo
    142 
    143 #endif  // MOJO_PUBLIC_CPP_BINDINGS_ARRAY_H_
    144