Boost, Metaprogramowanie, Inne biblioteki

Transkrypt

Boost, Metaprogramowanie, Inne biblioteki
Boost, Metaprogramowanie, Inne biblioteki
Biblioteka 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
Metaprogramowanie
Wprowadzenie
Coś poważniejszego
Inne podejście
4
Inne biblioteki
LEDA
Blitz++
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
Metaprogramowanie
Wprowadzenie
Coś poważniejszego
Inne podejście
4
Inne biblioteki
LEDA
Blitz++
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ówiona
w całości
Celem wykładu jest zaprezentowanie niektórych jej możliwości i zachęcenie
do samodzielnego zgłębienia szczegółów — więcej informacji:
http://www.boost.org/libs/regex/doc/index.html
B. 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ągu
wyraż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
1
Wykaz obejmuje najważniejsze elementy wyrażeń regularnych, ale nie jest kompletny
Sebastian 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
cout
cout
cout
cout
cout
cout
<<
<<
<<
<<
<<
<<
<<
regex_match(slowo, reg) << endl;
regex_match(NIP1, reg_NIP) << endl;
regex_match(NIP2, reg_NIP) << endl;
regex_match(NIP3, reg_NIP) << endl;
regex_match(NIP1, reg_NIP_alt) << endl;
regex_match(NIP2, reg_NIP_alt) << endl;
regex_match(NIP3, reg_NIP_alt) << endl;
//
//
//
//
//
//
//
1
1
0
0
1
0
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że
być 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 je
na 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że
być 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 je
na 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że
być 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 je
na podany ciąg
Sebastian Deorowicz (PŚl)
Boost, Metaprogramowanie, Inne biblioteki
2006–11-20
8 / 38
Biblioteka regex — algorytmy
Przykład
#include
#include
#include
#include
"stdafx.h"
<boost/regex.hpp>
<iostream>
<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;
}
Sebastian Deorowicz (PŚl)
// Ola ma kota, ale kot nie lubi Oli, za to lubi Asię
Boost, Metaprogramowanie, Inne biblioteki
2006–11-20
9 / 38
Biblioteka regex — iteratory
Przykład
#include
#include
#include
#include
#include
"stdafx.h"
<algorithm>
<boost/regex.hpp>
<iostream>
<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, &regex_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
Metaprogramowanie
Wprowadzenie
Coś poważniejszego
Inne podejście
4
Inne biblioteki
LEDA
Blitz++
Sebastian Deorowicz (PŚl)
Boost, Metaprogramowanie, Inne biblioteki
2006–11-20
11 / 38
Biblioteka graph
Możliwości
Reprezentacja grafów w pamięci komputera
Spora biblioteka gotowych algorytmów takich jak np.
algorytm Dijkstry
algorytm Floyda–Warshalla
algorytm Kruskala
przeszukiwanie grafu wszerz i w głąb
kolorowanie 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
#include
#include
#include
#include
#include
<iostream>
<cstdio>
<boost/graph/adjacency_list.hpp>
<boost/graph/breadth_first_search.hpp>
<boost/pending/integer_range.hpp>
<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;
};
2
Przykład z http://www.boost.org/libs/graph/example/bfs-example.cpp
Sebastian 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 use
typedef adjacency_list<vecS, vecS, undirectedS> graph_t;
// Set up the vertex IDs and names
enum {r, s, t, u, v, w, x, y, N};
const char *name = "rstuvwxy";
// Specify the edges in the graph
typedef 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 object
const 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));
// Typedefs
typedef 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 vertex
std::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 time
std::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
Metaprogramowanie
Wprowadzenie
Coś poważniejszego
Inne podejście
4
Inne biblioteki
LEDA
Blitz++
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;
cout << factorial<10>() << endl;
// 120
// 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
Metafunkcja
Jest obliczana w trakcie działania
programu
Może być wywoływana
z parametrem znanym dopiero
w czasie działania programu
Zajmuje niewiele miejsca w kodzie
Jest obliczana w trakcie kompilacji
programu — w trakcie działania
programu „wywołanie” sprowadza
się do podstawienia wyniku
Może być „wywoływana” tylko
z parametrem znanym w czasie
kompilacji
Muszą istnieć specjalizacje
dla wszystkich wartości
parametró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 problem
dla 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 problem
dla 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 problem
dla 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 wszystkich
niż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 wszystkich
niż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ść:
Sebastian Deorowicz (PŚl)
n
k
=
n−1
k −1
+
Boost, Metaprogramowanie, Inne biblioteki
n−1
k
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(n − 1) · · · (k + 1)
n!
=
k!(n − k)!
(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 wyniki
czą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 czasie
kompilacji — ich parametrami są wartości znane dopiero w czasie wykonywania
programu
Takie metafunkcje sprowadzają się więc w zasadzie do wygenerowania efektywnego
kodu na podstawie znanych niektórych parametrów problemu
Problem
Zabierzmy się za sortowanie
Istnieje wiele algorytmów sortowania, ale wybierzemy sortowanie przez proste
wstawianie, ponieważ dla małych danych jest ono bardzo wydajne — wydajniejsze
niż 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 parametrem
wzorca
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
if(A[N] >
A[N+1]
return
}
else
return
}
N> int inline inner_loop(int *A, const int x) {
x) {
= A[N];
inner_loop<N-1>(A, x);
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
N = 16
funkcja — 10.9ns
funkcja — 25.7ns
metafunkcja (1) — 4.7ns
metafunkcja (1) — 12.7ns
metafunkcja (2) — 4.9ns
metafunkcja (2) — 14.0ns
sort. szybkie — 20.0ns
sort. szybkie — 34.6ns
std::sort — 17.0ns
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
Metaprogramowanie
Wprowadzenie
Coś poważniejszego
Inne podejście
4
Inne biblioteki
LEDA
Blitz++
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
3
WWW: http://www.oonumerics.org/blitz/
Sebastian Deorowicz (PŚl)
Boost, Metaprogramowanie, Inne biblioteki
2006–11-20
37 / 38
Co za tydzień?
Spotykamy się o 12:15 w sali 732 w celu omówienia tematów projektów
Sebastian Deorowicz (PŚl)
Boost, Metaprogramowanie, Inne biblioteki
2006–11-20
38 / 38

Podobne dokumenty