text: // Licensed to the Apache Software Foundation (ASF) under one
  // or more contributor license agreements.  See the NOTICE file
  // distributed with this work for additional information
  // regarding copyright ownership.  The ASF licenses this file
  // to you under the Apache License, Version 2.0 (the
  // "License"); you may not use this file except in compliance
  // with the License.  You may obtain a copy of the License at
  //
  //   http://www.apache.org/licenses/LICENSE-2.0
  //
  // Unless required by applicable law or agreed to in writing,
  // software distributed under the License is distributed on an
  // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  // KIND, either express or implied.  See the License for the
  // specific language governing permissions and limitations
  // under the License.
  
  // Date: Sun Sep 20 12:25:11 CST 2015
  
  #ifndef  BVAR_VECTOR_H
  #define  BVAR_VECTOR_H
  
  #include <ostream>
  #include <gflags/gflags_declare.h>
  
  namespace bvar {
  
  DECLARE_bool(quote_vector);
  
  // Data inside a Vector will be plotted in a same graph.
  template <typename T, size_t N>
  class Vector {
  public:
      static const size_t WIDTH = N;
  
      Vector() {
          for (size_t i = 0; i < N; ++i) {
              _data[i] = T();
          }
      }
      
      Vector(const T& initial_value) {
          for (size_t i = 0; i < N; ++i) {
              _data[i] = initial_value;
          }
      }
      
      void operator+=(const Vector& rhs) {
          for (size_t i = 0; i < N; ++i) {
              _data[i] += rhs._data[i];
          }
      }
      
      void operator-=(const Vector& rhs) {
          for (size_t i = 0; i < N; ++i) {
              _data[i] -= rhs._data[i];
          }
      }
  
      template <typename S>
      void operator*=(const S& scalar) {
          for (size_t i = 0; i < N; ++i) {
              _data[i] *= scalar;
          }
      }
  
      template <typename S>
      void operator/=(const S& scalar) {
          for (size_t i = 0; i < N; ++i) {
              _data[i] /= scalar;
          }
      }
  
      bool operator==(const Vector& rhs) const {
          for (size_t i = 0; i < N; ++i) {
              if (!(_data[i] == rhs._data[i])) {
                  return false;
              }
          }
          return true;
      }
  
      bool operator!=(const Vector& rhs) const {
          return !operator==(rhs);
      }
      
      T& operator[](int index) { return _data[index]; }
      const T& operator[](int index) const { return _data[index]; }
  
  private:
      T _data[N];
  };
  
  template <typename T, size_t N>
  std::ostream& operator<<(std::ostream& os, const Vector<T, N>& vec) {
      if (FLAGS_quote_vector) {
          os << '"';
      }
      os << '[';
      if (N != 0) {
          os << vec[0];
          for (size_t i = 1; i < N; ++i) {
              os << ',' << vec[i];
          }
      }
      os << ']';
      if (FLAGS_quote_vector) {
          os << '"';
      }
      return os;
  }
  
  template <typename T>
  struct is_vector : public butil::false_type {};
  
  template <typename T, size_t N>
  struct is_vector<Vector<T,N> > : public butil::true_type {};
  
  }  // namespace bvar
  
  #endif  //BVAR_VECTOR_H
  