
//
// To jest przykładowy kod z podrozdziału 21.6.4 „Kontener unordered_map” książki
// "Programowanie. Teoria i praktyka z wykorzystaniem C++" Bjarne'a Stroustrupa.
//

#include "std_lib_facilities.h"

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

template<class In, class In2, class T, class BinOp, class BinOp2 >
T inner_product(In first, In last, In2 first2, T init, BinOp op, BinOp2 op2)
{
    while(first!=last) {
        init  = op(init, op2(*first, *first2));
        ++first;
        ++first2;
    }
    return init;
}

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

double weighted_value(
    const pair<string,double>& a,
    const pair<string,double>& b
)    // Wydobycie wartości i mnożenie.
{
    return a.second * b.second;
}

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

int main()
{
    // Tworzymy słownik (symbol,cena):

    unordered_map<string,double> dow_price;
    // Indeks Dow Jones Industrial (symbol,cena);
    // Aktualne kursy znajdują się na stronie www.djindexes.com.
    dow_price["MMM"] = 81.86; 
    dow_price ["AA"] = 34.69;
    dow_price ["MO"] = 54.45;
    // ...

    // Słownik (symbol,waga):

    unordered_map<string,double> dow_weight;            // dow (symbol,waga)

    dow_weight.insert(make_pair("MMM", 5.8549));    
    dow_weight.insert(make_pair("AA",2.4808));
    dow_weight.insert(make_pair("MO",3.8940));    
    // ...

    // Słownik (symbol,nazwa):

    unordered_map<string,string> dow_name;              // dow (symbol,nazwa)
    dow_name["MMM"] = "3M Co."; 
    dow_name["AA"]  = "Alcoa Inc.";
    dow_name["MO"]  = "Altria Group Inc.";
    // ...

    Dzięki powyższym słownikom można wygodnie pobrać wszystkie rodzaje informacji:

    double alcoa_price  = dow_price ["AA"];   // Odczytuje wartości ze słownika.
    double altria_price = dow_price ["MO"];

    if (dow_price.find("INTC") != dow_price.end()) // Znajduje pozycję w słowniku.
        cout << "Intel is in the Dow\n";

    typedef unordered_map<string,double>::const_iterator Dow_iterator;

    // Drukuje cenę każdej spółki w indeksie Dow:
    for (Dow_iterator p = dow_price.begin(); p!=dow_price.end(); ++p) {
        const string& symbol = p->first;      // symbol giełdowy
        cout << symbol << '\t'
             << p->second << '\t'
             << dow_name[symbol] << '\n';
    }

    double dji_index =
        inner_product(dow_price.begin(),      // wszystkie spółki
                      dow_price.end(),
                      dow_weight.begin(),     // wagi spółek
                      0.0,                    // wartość początkowa
                      plus<double>(),         // dodawanie (jak zwykle)
                      weighted_value);        // Wydobywa wartości i wagi oraz
                                              // mnoży je.
    cout << "DJI=" << dji_index << endl;
}

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