home *** CD-ROM | disk | FTP | other *** search
- //---------------------------------------------------------------------------
-
- #include <iostream>
- #include <vector>
- #include <algorithm>
- #include <functional>
-
- //---------------------------------------------------------------------------
- // soubor: f13_bitove_operatory.cpp
- // autor: Jaroslav Franek
- // vytvoreno: 20011123
- // copyright: (c) 2001 Jaroslav Franek
- // umisteni: Chip CD, rubrika Chip Plus, 02/02
- // reference: Jak se na funktor vola... II. dil, Chip 02/02
- // testovano v : Borland C++ Builder 5.0
- // nefunguje v : Microsoft Visual C++ .NET 7.0 (beta2), protoze tam chybi
- // parcialni specializace sablonove tridy iterator_traits
- // pro obycejny ukazatel
- //
- // komentar: jak napsat vlastni funtor - bitove operatory
- // stl poskytuje funktory pro logicke operatory,
- // ale ne pro bitove operatory, takze male cviceni:
- // napisem si je sami, nebudeme je ale strkat do
- // prostoru jmen 'std' - obycejny programator by nemel provadet
- // rozsirovani nebo upravy rozhranni standardni knihovny
- //
- //---------------------------------------------------------------------------
-
- //---------------------------------------------------------------------------
- //
- // bitove NOT, operator ~
- // T je ordinalni typ nebo trida pro kterou existuje pretizeny operator ~
- //
- //---------------------------------------------------------------------------
-
- template <class T> struct bitwise_not
- : public std::unary_function<T, T>
- {
- T operator ()(const T & arg) const
- {
- return ~arg;
- }
- };
-
- //---------------------------------------------------------------------------
- //
- // bitove AND, operator &
- // T je ordinalni typ nebo trida pro kterou existuje pretizeny operator &
- //
- //---------------------------------------------------------------------------
-
- template <class T> struct bitwise_and
- : public std::binary_function<T, T, T>
- {
- T operator ()(const T & arg1, const T & arg2) const
- {
- return arg1 & arg2;
- }
- };
-
- //---------------------------------------------------------------------------
- //
- // bitove OR, operator |
- // T je ordinalni typ nebo trida pro kterou existuje pretizeny operator |
- //
- //---------------------------------------------------------------------------
-
- template <class T> struct bitwise_or
- : public std::binary_function<T, T, T>
- {
- T operator ()(const T & arg1, const T & arg2) const
- {
- return arg1 | arg2;
- }
- };
-
- //---------------------------------------------------------------------------
- //
- // bitove XOR, operator ^
- // T je ordinalni typ nebo trida pro kterou existuje pretizeny operator ^
- //
- //---------------------------------------------------------------------------
-
- template <class T> struct bitwise_xor
- : public std::binary_function<T, T, T>
- {
- T operator ()(const T & arg1, const T & arg2) const
- {
- return arg1 ^ arg2;
- }
- };
-
- //---------------------------------------------------------------------------
- //
- // vypis po bitech
- // T je ordinalni typ
- //
- //---------------------------------------------------------------------------
-
- template <class T>
- std::ostream & write_bits(std::ostream & os, T x)
- {
- // kolik bitu ma jeden bajt, pro velikost pouzijeme typ std::size_t (tj. unsigned int)
- static const std::size_t bits_per_byte = 8;
-
- // kolik bitu ma hodnota typu T
- static const std::size_t max_bits = bits_per_byte * sizeof(T);
-
- int buff[max_bits];
-
- // maska pro jednotlive bity, nastavime na nejnizsi bit
- T mask(1);
-
- // prevedeni x na bity
- for ( std::size_t i = 0; i != max_bits ; ++i )
- {
- buff[max_bits - 1 - i] = (x & mask) ? 1 : 0;
- mask <<= 1; // posuneme masku o 1 pozici na nizsi bit
- }
-
- // vypis
- for ( std::size_t i = 0; i != max_bits ; ++i )
- {
- if ( !(os << buff[i]) )
- {
- break; // neco je spatne s 'os', prerusit smycku
- }
- }
- return os;
- }
-
- //---------------------------------------------------------------------------
- //
- // priklady pouziti
- //
- //---------------------------------------------------------------------------
-
- int main()
- {
-
- // nejdrive si pripravime kontejnery
- const int N = 9;
- int pole[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
-
- // a ted STL kontejnery
- // tohle uz umime: cisla1 se inicializuji prvky pole 'pole'
- std::vector<int> cisla1(pole, pole + N);
-
- // tohle je nove, cisla2 se inicializuje prvky pole 'pole', ale pozpatku
- // bohuzel Microsoft Visual C++ .NET 7.0 (beta2) tohle neskousne
- // reverse_iterator si podrobne predstavime nekdy priste
- std::vector<int> cisla2(std::reverse_iterator<int *>(pole + N),
- std::reverse_iterator<int *>(pole));
-
- // tohle je take nove: N prvku, kazdy nula
- std::vector<int> cisla3(N, 0);
-
- // vypiseme si je na obrazovku,
- std::cout << "cisla1 : ";
- std::copy(cisla1.begin(), cisla1.end(), std::ostream_iterator<int>(std::cout, " "));
- std::cout << "\n"
- "cisla2 : ";
- std::copy(cisla2.begin(), cisla2.end(), std::ostream_iterator<int>(std::cout, " "));
- std::cout << "\n"
- "cisla3 : ";
- std::copy(cisla3.begin(), cisla3.end(), std::ostream_iterator<int>(std::cout, " "));
- std::cout << std::endl;
-
- //*******************************************************************
- // a ted provedeme toto : cisla3 = NEG cisla1
- //
- std::transform(cisla1.begin(), cisla1.end(), cisla3.begin(), bitwise_not<int>());
- //*******************************************************************
-
- // vypiseme si je na obrazovku,
- std::cout << "NOT cisla1 : ";
- std::copy(cisla3.begin(), cisla3.end(), std::ostream_iterator<int>(std::cout, " "));
- // posledni prvky vypiseme po bitech, aby bylo zrejme, ze se to povedlo
- std::cout << "\n"
- "cisla1[N-1] : ";
- write_bits(std::cout, *(cisla1.end() - 1)); // o iteratorech podrobneji
- std::cout << "\n" // az nekdy priste
- "NOT cisla1[N-1] : ";
- write_bits(std::cout, *(cisla3.end() - 1));
- std::cout << std::endl;
-
- //*******************************************************************
- // a ted provedeme toto : cisla3 = cisla1 AND cisla2
- //
- std::transform(cisla1.begin(), cisla1.end(), cisla2.begin(), cisla3.begin(), bitwise_and<int>());
- //*******************************************************************
-
- // vypiseme si je na obrazovku,
- std::cout << "cisla1 AND cisla2 : ";
- std::copy(cisla3.begin(), cisla3.end(), std::ostream_iterator<int>(std::cout, " "));
- // posledni prvky vypiseme po bitech, aby bylo zrejme, ze se to povedlo
- std::cout << "\n"
- "cisla1[N-1] : ";
- write_bits(std::cout, *(cisla1.end() - 1));
- std::cout << "\n"
- "cisla2[N-1] : ";
- write_bits(std::cout, *(cisla2.end() - 1));
- std::cout << "\n"
- "cisla1[N-1] AND cisla2[N-1] : ";
- write_bits(std::cout, *(cisla3.end() - 1));
- std::cout << std::endl;
-
- //*******************************************************************
- // a ted provedeme toto : cisla3 = cisla1 OR cisla2
- //
- std::transform(cisla1.begin(), cisla1.end(), cisla2.begin(), cisla3.begin(), bitwise_or<int>());
- //*******************************************************************
-
- // vypiseme si je na obrazovku,
- std::cout << "cisla1 OR cisla2 : ";
- std::copy(cisla3.begin(), cisla3.end(), std::ostream_iterator<int>(std::cout, " "));
- // posledni prvky vypiseme po bitech, aby bylo zrejme, ze se to povedlo
- std::cout << "\n"
- "cisla1[N-1] : ";
- write_bits(std::cout, *(cisla1.end() - 1));
- std::cout << "\n"
- "cisla2[N-1] : ";
- write_bits(std::cout, *(cisla2.end() - 1));
- std::cout << "\n"
- "cisla1[N-1] OR cisla2[N-1] : ";
- write_bits(std::cout, *(cisla3.end() - 1));
- std::cout << std::endl;
-
- //*******************************************************************
- // a ted provedeme toto : cisla3 = cisla1 XOR cisla2
- //
- std::transform(cisla1.begin(), cisla1.end(), cisla2.begin(), cisla3.begin(), bitwise_xor<int>());
- //*******************************************************************
-
- // vypiseme si je na obrazovku,
- std::cout << "cisla1 XOR cisla2 : ";
- std::copy(cisla3.begin(), cisla3.end(), std::ostream_iterator<int>(std::cout, " "));
- // posledni prvky vypiseme po bitech, aby bylo zrejme, ze se to povedlo
- std::cout << "\n"
- "cisla1[N-1] : ";
- write_bits(std::cout, *(cisla1.end() - 1));
- std::cout << "\n"
- "cisla2[N-1] : ";
- write_bits(std::cout, *(cisla2.end() - 1));
- std::cout << "\n"
- "cisla1[N-1] XOR cisla2[N-1] : ";
- write_bits(std::cout, *(cisla3.end() - 1));
- std::cout << std::endl;
-
- // spravne vysledky si jiste dokazete overit sami
-
- return 0;
- }
- //---------------------------------------------------------------------------
-
-