// File:       vector.c++
// Version:    1.01
// Author:     (c) Miles Sabin, 1996
// Purpose:    approximation to ANSI C++ vector template

// Change log:
//  30/12/96   v. 1.00
//             Modified erase() so as not to invalidate iterators
//               before the erased sub-sequence. Consequently resizing
//               downward never happens.
//             Fixed overlap behaviour of insert_aux().
//  11/01/97   Fiddled with inlining a bit.
//  14/01/97   v. 1.01
//             Factored out non-generic code into vector_base.
//  16/01/97   Hoist helper is now a local static to avoid static init
//               problems.
//  23/01/97   Hoist helper is now a singleton.
//  23/02/97   Adapted to HoistHelper/HoistComparator split.
//  31/03/97   Added vector(size_t) constructor.
//  04/04/97   Replaced HoistComparators with HoistBinaryPredicates.

#include "vector.h"

#include "hoistbp.h"
#include "hoistctdt.h"
#include "newcasts.h"
#include "tpltutil.h"


// Implementation of vector<T>

#define reference             T&
#define const_reference       T const&
#define iterator              T*
#define const_iterator        T const*
#define size_type             size_t
#define difference_type       ptrdiff_t
#define value_type            T
#define rev_iterator          reverse_iterator<iterator, value_type, reference>
#define const_rev_iterator    reverse_iterator<const_iterator, value_type, const_reference>

#ifndef INSTANTIATE_VECTOR_COMPARATORS_ONLY

template<class T>
vector<T>::vector()
  : vector_base(get_hoist_constructor_destructor((T*)0))
  {}

#ifndef INSTANTIATE_VECTOR_NO_DEFAULT_CTOR

template<class T>
vector<T>::vector(size_type n)
  : vector_base(get_hoist_constructor_destructor((T*)0))
  {
    T value;
    vector_base::assign(n, &value);
  }

#endif

template<class T>
vector<T>::vector(size_type n, T const& value)
  : vector_base(get_hoist_constructor_destructor((T*)0), n , &value)
  {}

template<class T>
vector<T>::vector(T const* first, T const* last)
  : vector_base(get_hoist_constructor_destructor((T*)0), first, last)
  {}

template<class T>
vector<T>::vector(vector<T> const& rhs)
  : vector_base(rhs)
  {}

template<class T>
vector<T>::~vector()
  {}

template<class T>
const_iterator vector<T>::begin() const
  { return reinterpret_cast(T const*, vector_base::begin()); }

template<class T>
const_iterator vector<T>::end() const
  { return reinterpret_cast(T const*, vector_base::end()); }

template<class T>
const_rev_iterator vector<T>::rbegin() const
  { return const_rev_iterator(end()); }

template<class T>
const_rev_iterator vector<T>::rend() const
  { return const_rev_iterator(begin()); }

template<class T>
size_type vector<T>::size() const
  { return vector_base::size(); }

template<class T>
size_type vector<T>::max_size() const
  { return vector_base::max_size(); }

template<class T>
size_type vector<T>::capacity() const
  { return vector_base::capacity(); }

template<class T>
bool vector<T>::empty() const
  { return vector_base::empty(); }

template<class T>
const_reference vector<T>::operator[](size_type n) const
  { return *reinterpret_cast(T const*, vector_base::operator[](n)); }

template<class T>
const_reference vector<T>::at(size_type n) const
  { return *reinterpret_cast(T const*, vector_base::at(n)); }

template<class T>
const_reference vector<T>::front() const
  { return *reinterpret_cast(T const*, vector_base::front()); }

template<class T>
const_reference vector<T>::back() const
  { return *reinterpret_cast(T const*, vector_base::back()); }

template<class T>
vector<T>& vector<T>::operator=(vector<T> const& rhs)
  {
    vector_base::operator=(rhs);
    return *this;
  }

template<class T>
void vector<T>::assign(T const* first, T const* last)
  { vector_base::assign(first, last); }

template<class T>
void vector<T>::assign(size_type n, T const& t)
  { vector_base::assign(n, &t); }

template<class T>
iterator vector<T>::begin()
  { return reinterpret_cast(T*, vector_base::begin()); }

template<class T>
iterator vector<T>::end()
  { return reinterpret_cast(T*, vector_base::end()); }

template<class T>
rev_iterator vector<T>::rbegin()
  { return rev_iterator(end()); }

template<class T>
rev_iterator vector<T>::rend()
  { return rev_iterator(begin()); }

template<class T>
void vector<T>::resize(size_type sz, T const& c)
  { vector_base::resize(sz, &c); }

template<class T>
void vector<T>::reserve(size_type n)
  { vector_base::reserve(n); }

template<class T>
reference vector<T>::operator[](size_type n)
  { return *reinterpret_cast(T*, vector_base::operator[](n)); }

template<class T>
reference vector<T>::at(size_type n)
  { return *reinterpret_cast(T*, vector_base::at(n)); }

template<class T>
reference vector<T>::front()
  { return *reinterpret_cast(T*, vector_base::front()); }

template<class T>
reference vector<T>::back()
  { return *reinterpret_cast(T*, vector_base::back()); }

template<class T>
void vector<T>::push_back(T const& x)
  { vector_base::push_back(&x); }

template<class T>
void vector<T>::pop_back()
  { vector_base::pop_back(); }

template<class T>
iterator vector<T>::insert(iterator position, T const& x)
  { return reinterpret_cast(T*, vector_base::insert(position, &x)); }

template<class T>
void vector<T>::insert(iterator position, size_type n, T const& x)
  { vector_base::insert(position, n, &x); }

template<class T>
void vector<T>::insert(iterator position, T const* first, T const* last)
  { vector_base::insert(position, first, last); }

template<class T>
void vector<T>::erase(iterator position)
  { vector_base::erase(position); }

template<class T>
void vector<T>::erase(iterator first, iterator last)
  { vector_base::erase(first, last); }

template<class T>
void vector<T>::swap(vector<T>& x)
  { vector_base::swap(x); }

template<class T>
void vector<T>::clear()
  { vector_base::clear(); }

#endif

#undef reference
#undef const_reference
#undef iterator
#undef const_iterator
#undef size_type
#undef difference_type
#undef value_type
#undef rev_iterator
#undef const_rev_iterator

// Implementation of vector<T> free fns

#ifndef INSTANTIATE_VECTOR_NON_COMPARATORS_ONLY

template<class T>
bool operator==(vector<T> const& lhs, vector<T> const& rhs)
{
  return REF_reinterpret_cast(vector_base, lhs).is_equal(get_hoist_equal_to_comparator((T*)0), REF_reinterpret_cast(vector_base, rhs));
}

template<class T>
bool operator< (vector<T> const& lhs, vector<T> const& rhs)
{
  return REF_reinterpret_cast(vector_base, lhs).is_less_than(get_hoist_less_comparator((T*)0), REF_reinterpret_cast(vector_base, rhs));
}

#endif
