//  array



//  c-style array


#include <algorithm>
#include <iostream>
using std::cout; using std::sort;

void do_sort(int *values, int count)
{ // sort contents of array
  sort(values, values + count);
}

int main()
{ // demonstrate use of C-style array as STL sequence
  const int ELEMS = 6;
  int values[ELEMS] = { 3, 1, 4, 2, 9, 8 };
  for (int i = 0; i < ELEMS; ++i)
    cout << values[i] << ' ';
  cout << '\n';
  do_sort(values, ELEMS);
  for (int i = 0; i < ELEMS; ++i)
    cout << values[i] << ' ';
  cout << '\n';
  return 0;
}


//  tr1::array


#include <array>
#include <algorithm>
#include <iostream>
using std::cout; using std::sort;
using std::tr1::array;

template <class Container>
void do_sort(Container& values)
{ // sort contents of array
  sort(values.begin(), values.end());
}

int main()
{ // demonstrate use C-style array as STL sequence
  const int ELEMS = 6;
  array<int, ELEMS> values = { 3, 1, 4, 2, 9, 8 };
  for (int i = 0; i < ELEMS; ++i)
    cout << values[i] << ' ';
  cout << '\n';
  do_sort(values);
  for (int i = 0; i < ELEMS; ++i)
    cout << values[i] << ' ';
  cout << '\n';
  return 0;
}


//  array<T,N>  hold N object of type T in contiguous storage
//  &arr[n] == &arr[0]+n



#include <array>
#include <algorithm>
#include <iterator>
#include <ostream>
#include <iostream>
using std::tr1::array;
using std::basic_ostream; using std::cout;
using std::copy; using std::ostream_iterator;

class Elt
{ // class with non-trivial default constructor
public:
  Elt() : i(1) {}
  Elt(int ii) : i(ii) {}
private:
  template<class Elem, class Traits> friend
    basic_ostream<Elem, Traits>& operator<<(
      basic_ostream<Elem, Traits>&, const Elt&);
  int i;
};

template<class Elem, class Traits>
  basic_ostream<Elem, Traits>& operator<<(
    basic_ostream<Elem, Traits>& out, const Elt& elt)
{ // show object contents
  return out << elt.i;
}

int main()
{ // demonstrate default constructor and aggregate initialization
  array<Elt, 6> arr0;
  copy(arr0.begin(), arr0.end(),
    ostream_iterator<Elt>(cout, " "));
  cout << '\n';
  array<Elt, 6> arr1 = { 1, 2, 3, 4 };
  copy(arr1.begin(), arr1.end(),
    ostream_iterator<Elt>(cout, " "));
  cout << '\n';
  array<int, 6> arr2 = { 1, 2, 3, 4 };
  copy(arr2.begin(), arr2.end(),
    ostream_iterator<int>(cout, " "));
  cout << '\n';
  array<int, 6> arr3;
  copy(arr3.begin(), arr3.end(),
    ostream_iterator<int>(cout, " "));
  cout << '\n';
  array<int, 6> arr4 = {};
  copy(arr4.begin(), arr4.end(),
    ostream_iterator<int>(cout, " "));
  cout << '\n';
  return 0;
}


//  but copyable and assagnable


#include <array>
#include <algorithm>
#include <iterator>
#include <ostream>
#include <iostream>
using std::tr1::array;
using std::basic_ostream; using std::cout;
using std::copy; using std::ostream_iterator;

int main()
{ // demonstrate copying
  cout << "Original array: ";
  array<int, 6> arr0 = { 1, 1, 2, 3, 5, 8 };
  copy(arr0.begin(), arr0.end(),
    ostream_iterator<int>(cout, " "));
  cout << "\n  Copied array: ";
  array<int, 6> arr1 = arr0;
  copy(arr1.begin(), arr1.end(),
    ostream_iterator<int>(cout, " "));
  cout << "\n     New array: ";
  array<int, 6> arr2 = {};
  copy(arr2.begin(), arr2.end(),
    ostream_iterator<int>(cout, " "));
  cout << "\n    After copy: ";
  arr2 = arr0;
  copy(arr2.begin(), arr2.end(),
    ostream_iterator<int>(cout, " "));
  cout << '\n';
  return 0;
}


size_type  array<T,N>::size() const;
size_type  array<T,N>::max_size() const;
size_type  array<T,N>::empty() const;


reference        array<T,N>::operator[](size_type idx);
const_reference  array<T,N>::operator[](size_type idx) const;


reference        array<T,N>::at(size_type idx)
                                    throw(std::out_of_range);
const_reference  array<T,N>::at(size_type idx) const;
                                    throw(std::out_of_range);


reference        array<T,N>::front();
const_reference  array<T,N>::front() const;

reference        array<T,N>::back();
const_reference  array<T,N>::back() const;

T*          array<T,N>::data();
const T*    array<T,N>::data() const;


//  assign is different!!

void array<T,N>::assign(const T& val);    // N times  val
void array<T,N>::swap(array& rhs);        // exception safe


//  iterators: begin(), end(), rbegin(), rend()

//  lexicographical comparisions:
//  ==  !=  <  <=  >  >=


//  tuple-like interface

template <int Idx, class T, size_t N>
T& get(array<T,N>& arr);

template <int Idx, class T, size_t N>
const T& get(const array<T,N>& arr);