/*
 * @Author: iR
 * @Date: 2022-03-11 16:47:31
 * @LastEditors: iR
 * @LastEditTime: 2022-03-12 17:25:39
 * @FilePath: \Code\inc\vector.hpp
 * @Description:
 *
 * Copyright (c) 2022 by iR, All Rights Reserved.
 */
#ifndef _VECTOR_HPP_
#define _VECTOR_HPP_

#include <iostream>

template <class T>
class Vector
{
private:
  T *_v;
  int _len;
  int _used;

  void expand(); //扩容
  void shrink(); //缩容

protected:
  void adjust(); //调整容量接口

public:
  //无参数构造函数
  Vector();

  //初始长度构造函数
  Vector(int len);

  //构造函数-定义指定长度，相同初始值的向量
  // len 初始长度
  // value 初始值
  Vector(int len, T value);

  //析构函数
  ~Vector() { delete[] _v; }

  //获取值
  T &get(int a);

  //操作符重载
  T &operator[](int i);

  //某处更改为某值
  T put(int a, T value);

  //获取已使用数量
  int getused() const { return _used; }

  //模扩张到某值
  void expandTo(int a);

  int search(T value);

  void swap(int a, int b);

  int insert(int locate, int value);

  int remove(int locate, int value);

  int remove_sorted(int value);

  int find(int value);

  void bubbleSort();

  void printall();

  int getlen();

  int count(int value);

  void mergeSort(int lo, int hi);
};

template <class T>
Vector<T>::Vector()
{
  _used = 0;
  _len = 10;
  _v = new T[_len];
}

template <class T>
Vector<T>::Vector(int len)
{
  _used = 0;
  _len = 2 * len;
  _v = new T[_len];
}

template <class T>
Vector<T>::Vector(int len, T value)
{
  _used = len;
  _len = 2 * len;
  _v = new T[_len];
  for (int i = 0; i < _used; i++)
  {
    _v[i] = value;
  }
}

template <class T>
T &Vector<T>::get(int a)
{

  try
  {
    if (a >= 0 && a < _used)
      return _v[a];
    else
      throw "Error: Get vector data out of range!\n";
  }

  //异常处理
  catch (const char *msg)
  {
    std::cout << msg;
    return _v[0];
  }
}

template <class T>
T &Vector<T>::operator[](int a)
{
  try
  {
    if (a >= 0 && a < _used)
    {
      T &ref = _v[a];
      return ref;
    }
    else
      throw "Error: Request vercor data out of range!\n";
  }

  //异常处理
  catch (const char *msg)
  {
    std::cout << msg;
    return _v[0];
  }
}

template <class T>
T Vector<T>::put(int a, T value)
{

  //若不够，就扩容
  while (a > _used - 1)
  {
    _used++;
    adjust();
  }

  _v[a] = value;
  return _v[a];
}

template <class T>
void Vector<T>::expandTo(int a)
{
  while (a > _used - 1)
  {
    _used++;
    adjust();
  }
}

template <class T>
void Vector<T>::expand()
{

  int old_used = _used;
  _len = _len * 2;
  T *p = new T[_len];

  for (int i = 0; i < old_used; i++)
    p[i] = _v[i];

  delete[] _v;
  _v = p;
}

template <class T>
void Vector<T>::shrink()
{
  _len = _len / 2;
  T *p = new T[_len];

  for (int i = 0; i < _used; i++)
    p[i] = _v[i];

  delete[] _v;
  _v = p;
}

template <class T>
void Vector<T>::adjust()
{
  if (((double)_used / (double)_len) < 0.25)
    shrink();
  else if (((double)_used / (double)_len) > 0.75)
    expand();
  return;
}

#endif