
//
// To jest przykładowy kod z podrozdziału 19.3.4 „Liczby całkowite jako parametry szablonów” książki
// "Programowanie. Teoria i praktyka z wykorzystaniem C++" Bjarne'a Stroustrupa.
//

#include <iostream>
#include <vector>

using std::cout;
using std::vector;

//------------------------------------------------------------------------------

template<class T, int N> struct array {
    T elem[N];                  // Przechowuje elementy w tablicy składowej.

    // Polega na domyślnych konstruktorach, destruktorze i przypisaniu.

    T& operator[ ] (int n) { return elem[n]; } // dostęp: zwraca referencję
    const T& operator[ ] (int n) const { return elem[n]; }

    T* data() { return elem; }  // konwersja na T*
    const T* data() const { return elem; }

    int size() const  { return N; }    
};

//------------------------------------------------------------------------------

array<int,256> gb;          // 256 liczb całkowitych
array<double,6> ad = { 0.0, 1.1, 2.2, 3.3, 4.4, 5.5 };    // Zwróć uwagę na inicjator!
const int max = 1024;

void some_fct(int n)
{
    array<char,max> loc;
    //array<char,n> oops;         // Błąd: wartość n nie jest znana kompilatorowi.
    // ...
    array<char,max> loc2 = loc; // Tworzy kopię zapasową.
    // ...
    loc = loc2;                 // przywrócenie
    // ...
}

//------------------------------------------------------------------------------

template<class C> void printout(const C& c)
{
    for(int i = 0; i<c.size(); ++i) cout << c[i] <<'\n';
}

//------------------------------------------------------------------------------

int main(int argc, char* argv[])
{
    //double* p = ad;             // Błąd: nie można stosować niejawnej konwersji na wskaźnik.
    double* q = ad.data();      // Dobrze: jawna konwersja.

    printout(ad);               // wywołanie przez tablicę
    vector<int> vi;
    // ...
    printout(vi);               // wywołanie przez wektor
}

//------------------------------------------------------------------------------
