Domácí úkoly Pokročilé programování v C++ LS 2015/2016
NPRG051 Pokročilé programování v C++ - 2015/2016 - DÚ
1
DÚ 1 – continuation termín: pondělí 14.3. 23:59
NPRG051 Pokročilé programování v C++ - 2015/2016 - DÚ
2
DÚ 1 - continuation continuation f(int argc, char * * argv) {
Jednoduché použití
if (!argc)
return done();
std::cout << ">>" << argv[ 0] << std::endl;
return cont( f, argc - 1, argv + 1);
}
typ continuation funkce cont
funkce done
int main(int argc, char * * argv) {
vrací continuation obsahující pokyn zavolat danou funkci s danými parametry zadaná funkce vrací další continuation jako pokyn pokračovat dalším voláním vrací prázdné continuation
funkce run
spouští zadané funkce tak dlouho, dokud nejsou vyčerpány pokyny
run( cont( f, argc, argv)); return 0; }
NPRG051 Pokročilé programování v C++ - 2015/2016 - DÚ
3
DÚ 1 - continuation continuation k(const std::string & s) { std::cout << "\"" << s << "\"" << std::endl;
Složitější použití
typ continuation
return done();
}
continuation h(int argc, char * * argv) { auto s = cont(k, "The arguments are..."); for (int i = 0; i < argc; ++i) {
s &= cont(k, argv[i]); } return std::move(s) & cont(k, "The end");
podporuje zřetězení formou operátorů & a &= pokyny vlevo budou provedeny před pokyny vpravo nepodporuje kopírování, každý vytvořený pokyn může být proveden pouze jednou nutno používat move
funkce run
spouští zadané funkce tak dlouho, dokud nejsou vyčerpány pokyny pokynů může být více najednou pokyny vrácené z právě ukončené funkce mají přednost před staršími pokyny
}
NPRG051 Pokročilé programování v C++ - 2015/2016 - DÚ
4
DÚ 1 - continuation
Příklad odjinud – konstruktor std::thread (zjednodušeno)
template< class Function, class... Args > explicit thread( Function&& f, Args&&... args );
Creates new std::thread object and associates it with a thread of execution. First the constructor copies/moves all arguments (both the function object f and all args...) to thread-accessible storage as if by the function:
template
typename std::decay::type decay_copy(T&& v) { return std::forward(v); }
Let's refer to value_args as t1, t2, ..., tN, where N is sizeof...(value_args) and value_args is the result of calling decay_copy as defined above. The following code will be run in the new thread:
f(t1, t2, ..., tN);
t1, t2, ..., tN jsou rvalue (pozn. překladatele)
NPRG051 Pokročilé programování v C++ - 2015/2016 - DÚ
5
DÚ 1 - continuation
Příklad odjinud – pokračování
The arguments to the thread function are moved or copied by value. If a reference argument needs to be passed to the thread function, it has to be wrapped (e.g. with std::ref or std::cref).
void f1(int n); void f2(int& n); void test() { int n = 0; std::thread t2(f1, n); // pass by value std::thread t3(f2, std::ref(n)); // pass by reference t3.join();
// ensure that t3 is finished before n dies
std::cout << n; }
The copy constructor is deleted; threads are not copyable.
NPRG051 Pokročilé programování v C++ - 2015/2016 - DÚ
6
DÚ 1 - continuation
Rozbalení tuple do parametrů funkce
std::index_sequence je šablona parametrizovaná posloupností čísel std::make_index_sequence == std::index_sequence<0,1,...,n-1> tyto indexy jsou zapotřebí jako parametry funkce get pro přístup do šablony trik: pomocná funkce s přídavným argumentem, u nejž je zajímavý pouze typ
template void invoke_helper(Func&& func, Tup&& tup, std::index_sequence) { func(std::get(std::forward(tup))...); }
template void invoke(Func&& func, Tup&& tup) { const auto Size = std::tuple_size::type>::value; invoke_helper(std::forward(func), std::forward(tup), std::make_index_sequence<Size>{}); } NPRG051 Pokročilé programování v C++ - 2015/2016 - DÚ
7
Kritéria hodnocení
včasnost
přeložitelnost
rozhodně vyzkoušejte všechna možná přípustná data a typy
kultura kódu
nezávislost na OS, bitovosti, překladači - vyzkoušejte i gcc32/VS64
stabilita
přeložitelné bez chyb a (pokud možno) warningů kompatibilní s vzorem použití (rozhraní je pevné)
multiplatformnost
za nedodržení termínu body prudce dolů
pravidla, moudra, dobré zvyky, udržovatelnost, estetika, čitelnost
odevzdávací formality a konvence
názvy a struktura souborů, komentáře
NPRG051 Pokročilé programování v C++ - 2015/2016 - DÚ
8
Soubory DÚ 1
v du1.zip najdete 3 soubory
du1test.cpp
du1continuation.cpp, du1continuation.hpp
kód používající vaše řešení - neměňte - zachovat rozhraní! můžete (velmi doporučeno!) přidat vlastní testy sem doplňte kód a hlavičkový soubor vašeho řešení
soubory nepřejmenovávejte
na začátek každého souboru vložte komentář typu // du1continuation.hpp // Karel Vomacka NPRG051 2015/2016
vaše řešení vložte do Grupíčku - neposílejte emailem!
správné soubory do správných sloupečků!
NPRG051 Pokročilé programování v C++ - 2015/2016 - DÚ
9
DÚ 2 – PersistentMap termín: pondělí 11.4. 23:59
NPRG051 Pokročilé programování v C++ - 2015/2016 - DÚ
10
DÚ 2 - PersistentMap
PersistentMap
Podobný kontejner jako std::map Jednotlivé klíče a hodnoty se ukládájí do souborů Datová struktura je generická, tj. třída je šablona, která má dva parametry:
Naimplementujte základní operace:
typ klíče typ uložené struktury v souboru operator[] iterator find (const key_type& k); + const varianta std::pair insert(const std::pair& val); size_type erase(const key_type& k); iterátory – begin(), end(), const_begin(), const_end()
Kontejner umožňuje použití const iteratorů a implementuje move operace (move konstruktory a move přiřazovací operator) na dílčích strukturách – iterátory, ... Kopírování, přesouvání samotné persistentní mapy není definováno
NPRG051 Pokročilé programování v C++ - 2015/2016 - DÚ
11
DÚ 2 - PersistentMap using pm_t = PersistentMap<string,string>;
Jednoduché použití
pm_t myMap("TestDirectory");
myMap["file20.txt"] = "content 20"; myMap["file10.txt"] = "content 10";
inicializace PersistentMapy (PM) cestou ke složce s daty operátor hranatých závorek se chová obdobně jako u std::map
myMap["file15.txt"] = "content 15";
string f10 = myMap["file10.txt"]
std::string file; std::string content; for (auto& i : myMap) { tie(file, content) = i; cout << file << ": " << content << endl; }
pokud je složka TestDirectory před spuštěním programu prázdná, pak po spuštění programu má následující obsah:
NPRG051 Pokročilé programování v C++ - 2015/2016 - DÚ
umožňuje číst hodnotu z mapy pokud hodnota s daným indexem neexistuje, pak je vytvořena nová položka se stejným indexem umožňuje upravit hodnotu v PM
file10.txt - „content 10“ file15.txt - „content 15“ file20.txt - „content 20“ 12
DÚ 2 - PersistentMap using using using using using using using
key_type = ... mapped_type = ... value_type = ... reference = ... const_reference = ... pointer = ... const_pointer = ...
iterator begin(); iterator end(); const_iterator begin() const; const_iterator end() const; const_iterator cbegin() const; const_iterator cend() const;
Iterátory
kontejner umožňuje přístup k položkám skrze iterátory
nutné definovat veřejné aliasy datových typů
procházení položek v kontejneru
for (pm_t::iterator it = myMap.begin(); it != myMap.end(); ++it) { tie(file, content) = *it; cout << file << ": " << content << endl; }
NPRG051 Pokročilé programování v C++ - 2015/2016 - DÚ
Bidirectional Iterátory
pomocí iterátorů v setříděném pořadí nutné načíst všechny soubory v dané složce (nerekurzivně)
je možné použít algoritmy z STL
např.: std::copy
13
DÚ 2 - PersistentMap
Problémy
Jak pracovat s různými datovými typy
e.g. PersistentMap,
PersistentMap<string, vector<string>>
použijte definované trait třídy: KeySerializationTrait,
FileTypeSerializationTrait
výchozí implementace využívá std::stringstream k serializaci a deserializaci uživatel PM musí poskytnou vhodnou serializaci / deserializaci svých datových typů formou specializací šablon KeySerializationTrait, FileTypeSerializationTrait
template struct KeySerializationTrait { static string Serialize(const T& t) {stringstream ss; ss << t; return ss.str(); } static T Deserialize(const string& str) { T tmp; stringstream(str) >> tmp; return tmp; } }; template struct FileTypeSerializationTrait { static void Serialize(ostream& fileStream, const T& item) { fileStream << item; } static T Deserialize(istream& fileStream) { T tmp; fileStream >> tmp; return tmp; } };
NPRG051 Pokročilé programování v C++ - 2015/2016 - DÚ
14
DÚ 2 - PersistentMap
Problémy
Procházení souborů ve složce
Invalidace iterátorů
API funkce operačního systému nejnovější verze knihovny Boost (1.60.0)
funkce PM (operator[], find, insert, erase, begin, end, const_begin, const_end) iterátory stejně jako v std::map neinvalidují vyjímku tvoří pouze erase, který invaliduje iterátory ukazující na mazanou položku
Ukládání do / načítání ze souborů
k uloženým datům na disku lze přistupovat skrze nově inicializovanou PM po skončení platnosti instance PM, musí být data již zapsána na disk nesmí ovlivnit chování chování iterátorů
NPRG051 Pokročilé programování v C++ - 2015/2016 - DÚ
15
DÚ 2 - PersistentMap
Problémy
Jak odchytit čtení z/ zápis do položky (VOLITELNÉ – není nutné pro splnění DÚ)
operátor[] u std::map vrací referenci na std::map::value_type ( tedy std::map::value_type&) není podmínkou, aby PM vracela referenci na value_type lze vrátit instanci proxy třídy, která se stará o uložení / načtení správné hodnoty
implementace implicitních konverzních operátorů implementace konstruktorů, přiřazovacích operátorů platnost proměné může ovlivňovat její použití
operátor[] se musí chovat stejně jako v std::map řešení je dobré v okamžiku kdy více instancí sdílí stejné úložiště dat
NPRG051 Pokročilé programování v C++ - 2015/2016 - DÚ
16
DÚ 2 - PersistentMap
UPDATE
Předpokládejte, že datový typ, se kterou je PM použita, má výchozí konstruktor a je kopírovatelný
Nelze předpokládat, že data uložená na disku se celá vejdou do paměti
Předpokládejte, že položka PM žije po celou dobu existence objektů proxy třídy, které na ní odkazují.
tj. položka by měla být uložena v okamžiku, kdy poslední odkazující objekt proxy třídy byl destruován
případ int& var = pm_instance[key]; var = ...; tedy nenastane
Ošetření chybových stavů lze řešit funkcí, která vrací úspěšnost poslední provedené operace
NPRG051 Pokročilé programování v C++ - 2015/2016 - DÚ
17
Kritéria hodnocení
včasnost
přeložitelnost
rozhodně vyzkoušejte všechna možná přípustná data a typy
kultura kódu
nezávislost na OS, bitovosti, překladači - vyzkoušejte i gcc32/VS64
stabilita
přeložitelné bez chyb a (pokud možno) warningů kompatibilní s vzorem použití (rozhraní je pevné)
multiplatformnost
za nedodržení termínu body prudce dolů
pravidla, moudra, dobré zvyky, udržovatelnost, estetika, čitelnost
odevzdávací formality a konvence
názvy a struktura souborů, komentáře
NPRG051 Pokročilé programování v C++ - 2015/2016 - DÚ
18
Soubory DÚ 2 – PersistentMap
v du2_PersistentMap.zip najdete 3 zdrojové soubory
Main.cpp
PersistentMap.cpp, PersistentMap.hpp
kód používající vaše řešení - neměňte - zachovat rozhraní! můžete (velmi doporučeno!) přidat vlastní testy sem doplňte kód a hlavičkový soubor vašeho řešení
soubory nepřejmenovávejte
na začátek každého souboru vložte komentář typu // PersistentMap.hpp // Karel Vomacka NPRG051 2015/2016
vaše řešení vložte do Grupíčku - neposílejte emailem!
správné soubory do správných sloupečků!
knihovna Boost
pokud plánujete použít knihovnu boost, skripty pro její kompilaci najdete ve složce lib
NPRG051 Pokročilé programování v C++ - 2015/2016 - DÚ
19