Upload
hoangnhi
View
219
Download
0
Embed Size (px)
Citation preview
Boost, Metaprogramowanie, Inne bibliotekiBiblioteka STL
Sebastian Deorowicz
Politechnika Śląska
2006–11-20
Sebastian Deorowicz (PŚl) Boost, Metaprogramowanie, Inne biblioteki 2006–11-20 1 / 38
Plan wykładu
1 Biblioteka Regex (Boost)
2 Biblioteka Graph (Boost)
3 MetaprogramowanieWprowadzenieCoś poważniejszegoInne podejście
4 Inne bibliotekiLEDABlitz++
Sebastian Deorowicz (PŚl) Boost, Metaprogramowanie, Inne biblioteki 2006–11-20 2 / 38
Plan wykładu
1 Biblioteka Regex (Boost)
2 Biblioteka Graph (Boost)
3 MetaprogramowanieWprowadzenieCoś poważniejszegoInne podejście
4 Inne bibliotekiLEDABlitz++
Sebastian Deorowicz (PŚl) Boost, Metaprogramowanie, Inne biblioteki 2006–11-20 3 / 38
Biblioteka regex (Boost)
Opis
Standardowy język C++ nie udostępnia możliwości stosowania wyrażeń regularnych
Biblioteka regex (należąca do bibliotek Boost) wypełnia tę lukę
Biblioteka dostępna jest na darmowej licencji
Czym się teraz zajmiemy?
Podobnie jak w przypadku innych bibliotek Boost, regex nie zostanie omówionaw całościCelem wykładu jest zaprezentowanie niektórych jej możliwości i zachęceniedo samodzielnego zgłębienia szczegółów — więcej informacji:
http://www.boost.org/libs/regex/doc/index.htmlB. Karlsson, Więcej niż C++. Wprowadzenie do bibliotek Boost, Helion, 2006
Sebastian Deorowicz (PŚl) Boost, Metaprogramowanie, Inne biblioteki 2006–11-20 4 / 38
Biblioteka regex — wyrażenia regularne
Litery, cyfry, inne znaki1
Każdy symbol jest dopasowywany z takim samym z wyjątkiem znaków specjalnych:
. — dowolny znak
[ — definiuje zakresy symboli, np. [xyz] — dowolny z symboli xyz, [x-z] — to samo{ — definiuje liczbę powtórzeń:
{n} — poprzedni znak powinien wystąpić n razy{n,} — poprzedni znak powinien wystąpić co najmniej n razy{n,m} — poprzedni znak powinien wystąpić co najmniej n ale nie więcej niż m razy
(, ) — definiują podwyrażenie, które może być później używane w dalszym ciąguwyrażenia regularnego
* — poprzedni znak powinien wystąpić zero bądź więcej razy
+ — poprzedni znak powinien wystąpić raz bądź więcej razy
? — poprzedni znak powinien wystąpić zero raz bądź raz
| — alternatywa pomiędzy dwoma możliwościami
ˆ — początek wiersza
$ — koniec wiersza
1Wykaz obejmuje najważniejsze elementy wyrażeń regularnych, ale nie jest kompletnySebastian Deorowicz (PŚl) Boost, Metaprogramowanie, Inne biblioteki 2006–11-20 5 / 38
Biblioteka regex — przykład
Przykład
#include "stdafx.h"#include <boost/regex.hpp>#include <iostream>#include <string>using namespace std;using namespace boost;
int _tmain(int argc, _TCHAR* argv[]) {string slowo("Alicja");regex reg("[a-zA-Z]+");regex reg_NIP("\\d{3}-\\d{3}-\\d{2}-\\d{2}");string NIP1("645-000-01-02");string NIP2("645-00-101-02");string NIP3("645-00-01-102");regex reg_NIP_alt("\\d{3}-(\\d{3}-\\d{2}-\\d{2}|\\d{2}-\\d{2}-\\d{3})");
cout << regex_match(slowo, reg) << endl; // 1cout << regex_match(NIP1, reg_NIP) << endl; // 1cout << regex_match(NIP2, reg_NIP) << endl; // 0cout << regex_match(NIP3, reg_NIP) << endl; // 0cout << regex_match(NIP1, reg_NIP_alt) << endl; // 1cout << regex_match(NIP2, reg_NIP_alt) << endl; // 0cout << regex_match(NIP3, reg_NIP_alt) << endl; // 1
}
Sebastian Deorowicz (PŚl) Boost, Metaprogramowanie, Inne biblioteki 2006–11-20 6 / 38
Biblioteka regex
Wersje składni wyrażeń regularnych
Perl — domyślna
POSIX extended — kompatybilna z egrep i awk
POSIX basic — kompatybilna z grep i emacs
Wersje składni ciągów formatujących przy zastępowaniu znaków
Sed
Perl
Boost-Extended
Sebastian Deorowicz (PŚl) Boost, Metaprogramowanie, Inne biblioteki 2006–11-20 7 / 38
Biblioteka regex — algorytmy
regex match
Sprawdza czy podany ciąg jest zgodny z wyrażeniem regularnym
Istnieje kilka przeciążonych wersji tej funkcji, np. ciąg może być typu string, możebyć określony iteratorami
regex search
Sprawdza czy w podanym ciągu występuje fragment dający się dopasowaćdo wyrażenia regularnego
regex replace
Wyszukuje w podanym ciągu wszystkie dopasowania podanego ciągu i zamienia jena podany ciąg
Sebastian Deorowicz (PŚl) Boost, Metaprogramowanie, Inne biblioteki 2006–11-20 8 / 38
Biblioteka regex — algorytmy
regex match
Sprawdza czy podany ciąg jest zgodny z wyrażeniem regularnym
Istnieje kilka przeciążonych wersji tej funkcji, np. ciąg może być typu string, możebyć określony iteratorami
regex search
Sprawdza czy w podanym ciągu występuje fragment dający się dopasowaćdo wyrażenia regularnego
regex replace
Wyszukuje w podanym ciągu wszystkie dopasowania podanego ciągu i zamienia jena podany ciąg
Sebastian Deorowicz (PŚl) Boost, Metaprogramowanie, Inne biblioteki 2006–11-20 8 / 38
Biblioteka regex — algorytmy
regex match
Sprawdza czy podany ciąg jest zgodny z wyrażeniem regularnym
Istnieje kilka przeciążonych wersji tej funkcji, np. ciąg może być typu string, możebyć określony iteratorami
regex search
Sprawdza czy w podanym ciągu występuje fragment dający się dopasowaćdo wyrażenia regularnego
regex replace
Wyszukuje w podanym ciągu wszystkie dopasowania podanego ciągu i zamienia jena podany ciąg
Sebastian Deorowicz (PŚl) Boost, Metaprogramowanie, Inne biblioteki 2006–11-20 8 / 38
Biblioteka regex — algorytmy
Przykład
#include "stdafx.h"#include <boost/regex.hpp>#include <iostream>#include <string>
using namespace std;using namespace boost;
int _tmain(int argc, _TCHAR* argv[]) {string s("Ala ma kota, ale kot nie lubi Ali, za to lubi Asię");regex reg("(A)(l[a-zA-Z])", regex::perl);
s = regex_replace(s, reg, "O$2");cout << s << endl; // Ola ma kota, ale kot nie lubi Oli, za to lubi Asię}
Sebastian Deorowicz (PŚl) Boost, Metaprogramowanie, Inne biblioteki 2006–11-20 9 / 38
Biblioteka regex — iteratory
Przykład
#include "stdafx.h"#include <algorithm>#include <boost/regex.hpp>#include <iostream>#include <string>
using namespace std;using namespace boost;
bool regex_callback(const boost::match_results<std::string::const_iterator>& x) {cout << x[0].str() << endl;return true;
}
int _tmain(int argc, _TCHAR* argv[]) {string s("Firma usługowa 652-050-15-51\n652 Kowalski i spółka 625-15-54-505 (0-32)282-05-65");regex reg_NIP("\\d{3}-(\\d{3}-\\d{2}-\\d{2}|\\d{2}-\\d{2}-\\d{3})");
sregex_iterator p(s.begin(), s.end(), reg_NIP);sregex_iterator end;
for_each(p, end, ®ex_callback); // 652-050-15-51 625-15-54-505}
Sebastian Deorowicz (PŚl) Boost, Metaprogramowanie, Inne biblioteki 2006–11-20 10 / 38
Plan wykładu
1 Biblioteka Regex (Boost)
2 Biblioteka Graph (Boost)
3 MetaprogramowanieWprowadzenieCoś poważniejszegoInne podejście
4 Inne bibliotekiLEDABlitz++
Sebastian Deorowicz (PŚl) Boost, Metaprogramowanie, Inne biblioteki 2006–11-20 11 / 38
Biblioteka graph
Możliwości
Reprezentacja grafów w pamięci komputeraSpora biblioteka gotowych algorytmów takich jak np.
algorytm Dijkstryalgorytm Floyda–Warshallaalgorytm Kruskalaprzeszukiwanie grafu wszerz i w głąbkolorowanie grafu
Nieco trudniejsza w użyciu za to wydajnie zaimplementowana
Sebastian Deorowicz (PŚl) Boost, Metaprogramowanie, Inne biblioteki 2006–11-20 12 / 38
Biblioteka graph (cz.1)2
#include "stdafx.h"
#include <iostream>#include <cstdio>#include <boost/graph/adjacency_list.hpp>#include <boost/graph/breadth_first_search.hpp>#include <boost/pending/integer_range.hpp>#include <boost/pending/indirect_cmp.hpp>
using namespace boost;
template <typename TimeMap> class bfs_time_visitor:public default_bfs_visitor {typedef typename property_traits<TimeMap>::value_type T;
public:bfs_time_visitor(TimeMap tmap, T & t):m_timemap(tmap), m_time(t) { }template <typename Vertex, typename Graph>
void discover_vertex(Vertex u, const Graph & g) const{
put(m_timemap, u, m_time++);}TimeMap m_timemap;T & m_time;
};
2Przykład z http://www.boost.org/libs/graph/example/bfs-example.cppSebastian Deorowicz (PŚl) Boost, Metaprogramowanie, Inne biblioteki 2006–11-20 13 / 38
Biblioteka graph (cz.2)
int _tmain(int argc, _TCHAR* argv[]) {// Select the graph type we wish to usetypedef adjacency_list<vecS, vecS, undirectedS> graph_t;// Set up the vertex IDs and namesenum {r, s, t, u, v, w, x, y, N};const char *name = "rstuvwxy";// Specify the edges in the graphtypedef std::pair < int, int >E;E edge_array[] = { E(r, s), E(r, v), E(s, w), E(w, r), E(w, t),
E(w, x), E(x, t), E(t, u), E(x, y), E(u, y)};// Create the graph objectconst int n_edges = sizeof(edge_array) / sizeof(E);typedef graph_traits<graph_t>::vertices_size_type v_size_t;graph_t g(edge_array, edge_array + n_edges, v_size_t(N));
// Typedefstypedef graph_traits<graph_t>::vertex_descriptor Vertex;typedef graph_traits<graph_t>::vertices_size_type Size;typedef Size* Iiter;
// a vector to hold the discover time property for each vertexstd::vector<Size> dtime(num_vertices(g));
Size time = 0;bfs_time_visitor<Size*>vis(&dtime[0], time);breadth_first_search(g, vertex(s, g), visitor(vis));
// Use std::sort to order the vertices by their discover timestd::vector<graph_traits<graph_t>::vertices_size_type > discover_order(N);integer_range < int >range(0, N);std::copy(range.begin(), range.end(), discover_order.begin());std::sort(discover_order.begin(), discover_order.end(), indirect_cmp<Iiter, std::less<Size> >(&dtime[0]));
std::cout << "order of discovery: ";for (int i = 0; i < N; ++i)
std::cout << name[discover_order[i]] << " ";std::cout << std::endl;
}Sebastian Deorowicz (PŚl) Boost, Metaprogramowanie, Inne biblioteki 2006–11-20 14 / 38
Plan wykładu
1 Biblioteka Regex (Boost)
2 Biblioteka Graph (Boost)
3 MetaprogramowanieWprowadzenieCoś poważniejszegoInne podejście
4 Inne bibliotekiLEDABlitz++
Sebastian Deorowicz (PŚl) Boost, Metaprogramowanie, Inne biblioteki 2006–11-20 15 / 38
Metaprogramowanie
Czym jest metaprogramowanie?
Tworzenie programów wykonywanych w czasie kompilacji
Metaprogram modyfikuje kod programu
Polecana literatura
D. Vandevoorde, N. Josuttis, C++. Szablony. Vademecum profesjonalisty, Helion,2003.
D. Abrahams, A. Gurtovoy, Język C++. Metaprogramowanie za pomocą szablonów,Helion, 2005.
Sebastian Deorowicz (PŚl) Boost, Metaprogramowanie, Inne biblioteki 2006–11-20 16 / 38
Metaprogramowanie
Czym jest metaprogramowanie?
Tworzenie programów wykonywanych w czasie kompilacji
Metaprogram modyfikuje kod programu
Polecana literatura
D. Vandevoorde, N. Josuttis, C++. Szablony. Vademecum profesjonalisty, Helion,2003.
D. Abrahams, A. Gurtovoy, Język C++. Metaprogramowanie za pomocą szablonów,Helion, 2005.
Sebastian Deorowicz (PŚl) Boost, Metaprogramowanie, Inne biblioteki 2006–11-20 16 / 38
Metaprogramowanie (przykłady) — silnia
Przykład
unsigned factorial_fun(unsigned n) {int r;for(r = 1; n > 0; n--)
r *= n;return r;
}
...
cout << factorial_fun(5) << endl; // 120
Opis
Funkcja wykonywana jest w trakcie działania programu
Złożoność liniowa względem parametru
Sebastian Deorowicz (PŚl) Boost, Metaprogramowanie, Inne biblioteki 2006–11-20 17 / 38
Metaprogramowanie (przykłady) — silnia
Przykład
template<unsigned N> inline unsigned factorial(void) {return factorial<N-1>() * N;
}
template<> inline unsigned factorial<0>(void) {return 1;
}
...
cout << factorial<5>() << endl; // 120cout << factorial<10>() << endl; // 3628800
Opis
Metafunkcja wykonywana jest w trakcie kompilacji
W czasie działania programu podstawiany jest tylko konkretny wynik — złożonośćstała
Sebastian Deorowicz (PŚl) Boost, Metaprogramowanie, Inne biblioteki 2006–11-20 18 / 38
Programowanie a metaprogramowanie
Funkcja
Jest obliczana w trakcie działaniaprogramu
Może być wywoływanaz parametrem znanym dopierow czasie działania programu
Zajmuje niewiele miejsca w kodzie
Metafunkcja
Jest obliczana w trakcie kompilacjiprogramu — w trakcie działaniaprogramu „wywołanie” sprowadzasię do podstawienia wyniku
Może być „wywoływana” tylkoz parametrem znanym w czasiekompilacji
Muszą istnieć specjalizacjedla wszystkich wartościparametrów użytych w programie
Sebastian Deorowicz (PŚl) Boost, Metaprogramowanie, Inne biblioteki 2006–11-20 19 / 38
Metaprogramowanie
Jak przerabiać kod na metakod?
Do dyspozycji mamy wzorce
Parametrami nie-typami wzorca mogą być tylko liczby całkowite
Metaprogramowanie za pomocą wzorców bazuje na rekurencji — algorytm musi być(albo musi się dać przerobić na) rekurencyjny
Problem
Wzorce funkcji nie mogą być specjalizowane tylko częściowo — nie był to problemdla funkcji silnia, ale już przy potęgowaniu tak łatwo się nie da
Rozwiązanie
Wzorce klas mogą być specjalizowane częściowo — trzeba przejść z funkcji na klasy
Sebastian Deorowicz (PŚl) Boost, Metaprogramowanie, Inne biblioteki 2006–11-20 20 / 38
Metaprogramowanie
Jak przerabiać kod na metakod?
Do dyspozycji mamy wzorce
Parametrami nie-typami wzorca mogą być tylko liczby całkowite
Metaprogramowanie za pomocą wzorców bazuje na rekurencji — algorytm musi być(albo musi się dać przerobić na) rekurencyjny
Problem
Wzorce funkcji nie mogą być specjalizowane tylko częściowo — nie był to problemdla funkcji silnia, ale już przy potęgowaniu tak łatwo się nie da
Rozwiązanie
Wzorce klas mogą być specjalizowane częściowo — trzeba przejść z funkcji na klasy
Sebastian Deorowicz (PŚl) Boost, Metaprogramowanie, Inne biblioteki 2006–11-20 20 / 38
Metaprogramowanie
Jak przerabiać kod na metakod?
Do dyspozycji mamy wzorce
Parametrami nie-typami wzorca mogą być tylko liczby całkowite
Metaprogramowanie za pomocą wzorców bazuje na rekurencji — algorytm musi być(albo musi się dać przerobić na) rekurencyjny
Problem
Wzorce funkcji nie mogą być specjalizowane tylko częściowo — nie był to problemdla funkcji silnia, ale już przy potęgowaniu tak łatwo się nie da
Rozwiązanie
Wzorce klas mogą być specjalizowane częściowo — trzeba przejść z funkcji na klasy
Sebastian Deorowicz (PŚl) Boost, Metaprogramowanie, Inne biblioteki 2006–11-20 20 / 38
Metaprogramowanie (przykłady) — potęgowanie
Przykład
template<unsigned X, unsigned Y> struct power {static unsigned const value = X * power<X,Y-1>::value;
};template<unsigned X> struct power<X, 0> {
static unsigned const value = 1;};
...
cout << power<2,5>::value << endl;cout << power<5,4>::value << endl;
Co się tu dzieje?
Klasa nie może zwracać wyniku, ale może mieć pola statyczne
Pola te istnieją niezależnie od tego czy mamy obiekty klas
Klasa jest tzw. otoczką zmiennej
Sebastian Deorowicz (PŚl) Boost, Metaprogramowanie, Inne biblioteki 2006–11-20 21 / 38
Metaprogramowanie (przykłady) — potęgowanie
Czy jest ono kosztowne?
W czasie wykonywania wiele nas nie kosztuje
W czasie kompilacji dla potęgi trzeba wyznaczyć stworzyć konkretyzacje wszystkichniższych potęg
To samo można jednak zrobić nieco lepiej
Przykład
template<unsigned X, unsigned Y> struct power2 {static unsigned const value = power2<X,Y/2>::value * power2<X,(Y-Y/2)>::value;
};
template<unsigned X> struct power2<X, 1> {static unsigned const value = X;
};
template<unsigned X> struct power2<X, 0> {static unsigned const value = 1;
};
...cout << power<2,5>::value << endl;cout << power<5,4>::value << endl;
Sebastian Deorowicz (PŚl) Boost, Metaprogramowanie, Inne biblioteki 2006–11-20 22 / 38
Metaprogramowanie (przykłady) — potęgowanie
Czy jest ono kosztowne?
W czasie wykonywania wiele nas nie kosztuje
W czasie kompilacji dla potęgi trzeba wyznaczyć stworzyć konkretyzacje wszystkichniższych potęg
To samo można jednak zrobić nieco lepiej
Przykład
template<unsigned X, unsigned Y> struct power2 {static unsigned const value = power2<X,Y/2>::value * power2<X,(Y-Y/2)>::value;
};
template<unsigned X> struct power2<X, 1> {static unsigned const value = X;
};
template<unsigned X> struct power2<X, 0> {static unsigned const value = 1;
};
...cout << power<2,5>::value << endl;cout << power<5,4>::value << endl;
Sebastian Deorowicz (PŚl) Boost, Metaprogramowanie, Inne biblioteki 2006–11-20 22 / 38
Metaprogramowanie
Inny problem
Spróbujmy obliczać wartości współczynników dwumianowych
Zrobimy to na podstawie trójkąta Pascala, tj. wykorzystamy zależność:(nk
)=
(n − 1k − 1
)+
(n − 1k
)
Sebastian Deorowicz (PŚl) Boost, Metaprogramowanie, Inne biblioteki 2006–11-20 23 / 38
Metaprogramowanie — współczynniki dwumianowe (metaprogram)
Przykład
template<unsigned N, unsigned K> struct slow_binomial {static unsigned const value = slow_binomial<N-1,K-1>::value + slow_binomial<N-1,K>::value;
};
template<unsigned N> struct slow_binomial<N, 0> {static unsigned const value = 1;
};
template<unsigned N> struct slow_binomial<N, N> {static unsigned const value = 1;
};
template<> struct slow_binomial<0, 0> {static unsigned const value = 1;
};
...
cout << slow_binomial<10,5>::value << endl;
Sebastian Deorowicz (PŚl) Boost, Metaprogramowanie, Inne biblioteki 2006–11-20 24 / 38
Metaprogramowanie — współczynniki dwumianowe
Czy to dużo kosztuje?
Trzeba wykonać O(nk) konkretyzacji — bo obliczenie wykonywane jest za pomocątrójkąta Pascala
Czy można lepiej?
Oczywiście — wystarczy liczyć współczynnik ze wzoru:
n!k!(n − k)! =
n(n − 1) · · · (k + 1)(n − k)(n − k − 1) · · · 1
Dzięki temu potrzebnych będzie tylko O(n) specjalizacji
Sebastian Deorowicz (PŚl) Boost, Metaprogramowanie, Inne biblioteki 2006–11-20 25 / 38
Metaprogramowanie — współczynniki dwumianowe (wersja 2)
Przykład
template<unsigned N, unsigned K> struct partial_factorial {static unsigned const value = N * partial_factorial<N-1,K>::value;
};
template<unsigned N> struct partial_factorial<N,N> {static unsigned const value = 1;
};
template<unsigned N, unsigned K> struct fast_binomial {static unsigned const value = partial_factorial<N,K>::value / partial_factorial<N-K,0>::value;
};
...
cout << fast_binomial<10,5>::value << endl;
Sebastian Deorowicz (PŚl) Boost, Metaprogramowanie, Inne biblioteki 2006–11-20 26 / 38
Metaprogramowanie — współczynniki dwumianowe
Porównanie wersji
Wersja 1 generuje dużo więcej kodu niż wersja 2
Wersja 2 może dawać błędne wyniki nawet jeśli wynik jest w zakresie int, bo wynikicząstkowe (w liczniku i w mianowniku) mogą przekroczyć zakres
Wersja 1 da poprawny wynik końcowy jeśli tylko mieści się on w zakresie int
Sebastian Deorowicz (PŚl) Boost, Metaprogramowanie, Inne biblioteki 2006–11-20 27 / 38
Metaprogramowanie
Opis
Do tej pory tworzyliśmy metafunkcje w pełni obliczane w czasie kompilacji
Możliwe jest jednak też tworzenie metafunkcji tylko częściowo obliczanych w czasiekompilacji — ich parametrami są wartości znane dopiero w czasie wykonywaniaprogramu
Takie metafunkcje sprowadzają się więc w zasadzie do wygenerowania efektywnegokodu na podstawie znanych niektórych parametrów problemu
Problem
Zabierzmy się za sortowanie
Istnieje wiele algorytmów sortowania, ale wybierzemy sortowanie przez prostewstawianie, ponieważ dla małych danych jest ono bardzo wydajne — wydajniejszeniż sortowanie szybkie
Sebastian Deorowicz (PŚl) Boost, Metaprogramowanie, Inne biblioteki 2006–11-20 28 / 38
Metaprogramowanie — sortowanie przez wstawianie
Przykład
void insertion_sort(int *A, int n){
for(int i = 1; i < n; i++) {int x = A[i];int j;for(j = i-1; j >= 0 && A[j] > x; j--)
A[j+1] = A[j];A[j+1] = x;
}}
Problem
Brak rekurencji, więc trzeba ten kod najpierw przerobić — na szczęście pętle siębardzo łatwo przerabia
Sebastian Deorowicz (PŚl) Boost, Metaprogramowanie, Inne biblioteki 2006–11-20 29 / 38
Metaprogramowanie — sortowanie przez wstawianie
Przykład
int inline inner_loop(int *A, const int n, const int x) {if(n >= 0) {
if(A[n] > x) {A[n+1] = A[n];return inner_loop(A, n-1, x);
}else
return n;}return -1;
}
void insertion_sort2(int *A, int n) {for(int i = 1; i < n; i++) {
int x = A[i];int j = inner_loop(A, i-1, x);A[j+1] = x;
}}
Co teraz?
Teraz przejdziemy na metaprogram, w którym rozmiar tablicy będzie parametremwzorca
Dane do sortowania będą parametrem funkcji
Sebastian Deorowicz (PŚl) Boost, Metaprogramowanie, Inne biblioteki 2006–11-20 30 / 38
Metaprogramowanie — sortowanie przez wstawianie (wersja 1)
Przykład
template<int N> int inline inner_loop(int *A, const int x) {if(A[N] > x) {
A[N+1] = A[N];return inner_loop<N-1>(A, x);
}else
return N;}
template<> int inline inner_loop<-1>(int *A, const int x) {return -1;
}
template<int N> void inline insertion_sort(int *A) {insertion_sort<N-1>(A);int x = A[N-1];A[inner_loop<N-2>(A, x)+1] = x;
}
template<> void inline insertion_sort<0>(int *A){}
template<> void inline insertion_sort<1>(int *A){}
Sebastian Deorowicz (PŚl) Boost, Metaprogramowanie, Inne biblioteki 2006–11-20 31 / 38
Metaprogramowanie — sortowanie przez wstawianie (wersja 2)
Przykład
template<int N> inline void inner_loop(int *A) {if(A[N] < A[N-1]) {
std::swap(A[N], A[N-1]);inner_loop<N-1>(A);
}};
template<> inline void inner_loop<0>(int *A){};
template<int N> inline void insertion_sort(int *A) {insertion_sort<N-1>(A);inner_loop<N-1>(A);
};
template<> inline void insertion_sort<0>(int *A){};
template<> inline void insertion_sort<1>(int *A){};
Sebastian Deorowicz (PŚl) Boost, Metaprogramowanie, Inne biblioteki 2006–11-20 32 / 38
Metaprogramowanie — testy porównawcze
N = 10
funkcja — 10.9ns
metafunkcja (1) — 4.7ns
metafunkcja (2) — 4.9ns
sort. szybkie — 20.0ns
std::sort — 17.0ns
N = 16
funkcja — 25.7ns
metafunkcja (1) — 12.7ns
metafunkcja (2) — 14.0ns
sort. szybkie — 34.6ns
std::sort — 30.3ns
Sebastian Deorowicz (PŚl) Boost, Metaprogramowanie, Inne biblioteki 2006–11-20 33 / 38
Metaprogramowanie — Biblioteka MPL
Czym jest?
Ogólna biblioteka wspomagająca metaprogramowanie
Część Boost
Zawiera sekwencje, iteratory, algorytmy (podobne do tych z STL) czasu kompilacji
Sebastian Deorowicz (PŚl) Boost, Metaprogramowanie, Inne biblioteki 2006–11-20 34 / 38
Plan wykładu
1 Biblioteka Regex (Boost)
2 Biblioteka Graph (Boost)
3 MetaprogramowanieWprowadzenieCoś poważniejszegoInne podejście
4 Inne bibliotekiLEDABlitz++
Sebastian Deorowicz (PŚl) Boost, Metaprogramowanie, Inne biblioteki 2006–11-20 35 / 38
LEDA
Czym jest LEDA?
Zaawansowana biblioteka struktur danych i algorytmów
URL: www.leda.org
Zalety
Bardzo duża liczba gotowych struktur danych i algorytmów
Duża wygoda użytkowania
Wady
Wysoka cena: kilka (kilkanaście) tysięcy Euro w zależności od wersji
Sebastian Deorowicz (PŚl) Boost, Metaprogramowanie, Inne biblioteki 2006–11-20 36 / 38
Blitz++
Czym jest Blitz++?3
Biblioteka specjalizowana dla obliczeń naukowych
Dostępna na licencji GNU GPL
3WWW: http://www.oonumerics.org/blitz/Sebastian Deorowicz (PŚl) Boost, Metaprogramowanie, Inne biblioteki 2006–11-20 37 / 38