//  Example 10.5, page 230
//  Schaum's Outline of Fundamental of Computing with C++
//  by John R. Hubbard
//  Copyright McGraw-Hill, 1998

#include <iostream>
#include <vector>
#include <cassert>
#include <typeinfo>

using namespace std;

typedef vector<double> vec;
typedef vector<bool> bits;

/*Write a function that returns a vector of integers that
conains alternating elements of two integer vectors called
a and b.  Begin ewith the first element of a, then
alternate until one of the vectos is out of elements.
After that point, simply include the
remaining elemetns of the longer vector. For example
a = {1,2,3} and b={8,10,12,14,5,42} should return
merge(a,b) = {1,8,2,10,3,12,14,5,42}
*/

vector<int>& merge(vector<int>& a, vector<int>& b) {
    vector<int> c;
    //vector<int>::iterator
    auto a_it = a.begin(), b_it = b.begin();
    cout << "\nauto is " << typeid(a_it).name();
    while(a_it != a.end() && b_it != b.end()) {
        c.push_back(*a_it++);
        c.push_back(*b_it++);
    }
    while(a_it != a.end()) c.push_back(*a_it++);
    while(b_it != b.end()) c.push_back(*b_it++);
    return c;
}

template <class T>
void copy(vector<T>& v, const T* x, int n)
{
    vector<T> w;
    for (int i=0; i<n; i++)
        w.push_back(x[i]);
    v = w;
}

vec projection(vec& v, bits& b)
{   int v_size = v.size();
    assert(b.size() >= v_size);
    vec w;
    for (int i=0; i<v_size; i++)
        if (b[i]) w.push_back(v[i]);
    return w;
}
template <typename T>
void print(vector<T> v)
{   int v_size = v.size();
    for (int i=0; i<v_size; i++)
        cout << v[i] << "  ";
    cout << endl;
}

int main()
{   double x[8] = { 22.2, 33.3, 44.4, 55.5, 66.6, 77.7, 88.8, 99.9 };
    vec v;
    copy(v, x, 8);
    bool y[8] = { false, true, false, true, true, true, false, true };
    bits b;
    copy(b, y, 8);
    vec w = projection(v, b);
    cout << "\nv = ";
    print<double>(v);
    cout << "\nb = ";
    print<bool>(b);
    cout << "\nw = ";
    print<double>(w);
    int z1[4] = { 50, 60, 70, 80};
    int z2[6] = { 9, 8, 7, 6, 5, 4};
    vector<int> a, d, c;
    copy(a, z1, 4);
    copy(d, z2, 6);
    c = merge(a,d);
    cout << "\nc = ";
    print<int>(c);

}
