home *** CD-ROM | disk | FTP | other *** search
/ Chip 2002 February / Chip_2002-02_cd1.bin / chplus / funktor / f13_bitove_operatory_mvc7.cpp < prev    next >
C/C++ Source or Header  |  2002-01-02  |  9KB  |  256 lines

  1. //---------------------------------------------------------------------------
  2.  
  3. #include <iostream>
  4. #include <vector>
  5. #include <algorithm>
  6. #include <functional>
  7.  
  8. //---------------------------------------------------------------------------
  9. //  soubor:    f13_bitove_operatory.cpp
  10. //  autor:     Jaroslav Franek
  11. //  vytvoreno: 20011123
  12. //  copyright: (c) 2001 Jaroslav Franek
  13. //  umisteni:  Chip CD, rubrika Chip Plus, 02/02
  14. //  reference: Jak se na funktor vola... II. dil, Chip 02/02
  15. //  testovano v : Borland C++ Builder 5.0
  16. //                Microsoft Visual C++ .NET 7.0 (beta2) (upraveno specielne pro...)
  17. //
  18. //  komentar:  jak napsat vlastni funtor - bitove operatory
  19. //             stl poskytuje funktory pro logicke operatory,
  20. //             ale ne pro bitove operatory, takze male cviceni:
  21. //             napisem si je sami, nebudeme je ale strkat do
  22. //             prostoru jmen 'std' - obycejny programator by nemel provadet
  23. //             rozsirovani nebo upravy rozhranni standardni knihovny
  24. //
  25. //---------------------------------------------------------------------------
  26.  
  27. //---------------------------------------------------------------------------
  28. //
  29. //  bitove NOT, operator ~
  30. //  T je ordinalni typ nebo trida pro kterou existuje pretizeny operator ~
  31. //
  32. //---------------------------------------------------------------------------
  33.  
  34. template <class T> struct bitwise_not
  35.    : public std::unary_function<T, T>
  36. {
  37.    T operator ()(const T & arg) const
  38.       {
  39.          return ~arg;
  40.       }
  41. };
  42.  
  43. //---------------------------------------------------------------------------
  44. //
  45. //  bitove AND, operator &
  46. //  T je ordinalni typ nebo trida pro kterou existuje pretizeny operator &
  47. //
  48. //---------------------------------------------------------------------------
  49.  
  50. template <class T> struct bitwise_and
  51.    : public std::binary_function<T, T, T>
  52. {
  53.    T operator ()(const T & arg1, const T & arg2) const
  54.       {
  55.          return arg1 & arg2;
  56.       }
  57. };
  58.  
  59. //---------------------------------------------------------------------------
  60. //
  61. //  bitove OR, operator |
  62. //  T je ordinalni typ nebo trida pro kterou existuje pretizeny operator |
  63. //
  64. //---------------------------------------------------------------------------
  65.  
  66. template <class T> struct bitwise_or
  67.    : public std::binary_function<T, T, T>
  68. {
  69.    T operator ()(const T & arg1, const T & arg2) const
  70.       {
  71.          return arg1 | arg2;
  72.       }
  73. };
  74.  
  75. //---------------------------------------------------------------------------
  76. //
  77. //  bitove XOR, operator ^
  78. //  T je ordinalni typ nebo trida pro kterou existuje pretizeny operator ^
  79. //
  80. //---------------------------------------------------------------------------
  81.  
  82. template <class T> struct bitwise_xor
  83.    : public std::binary_function<T, T, T>
  84. {
  85.    T operator ()(const T & arg1, const T & arg2) const
  86.       {
  87.          return arg1 ^ arg2;
  88.       }
  89. };
  90.  
  91. //---------------------------------------------------------------------------
  92. //
  93. //  vypis po bitech
  94. //  T je ordinalni typ
  95. //
  96. //---------------------------------------------------------------------------
  97.  
  98. template <class T>
  99. std::ostream & write_bits(std::ostream & os, T x)
  100. {
  101.    // kolik bitu ma jeden bajt, pro velikost pouzijeme typ std::size_t (tj. unsigned int)
  102.    static const std::size_t bits_per_byte = 8;
  103.  
  104.    // kolik bitu ma hodnota typu T
  105.    static const std::size_t max_bits = bits_per_byte * sizeof(T);
  106.  
  107.    int buff[max_bits];
  108.  
  109.    // maska pro jednotlive bity, nastavime na nejnizsi bit
  110.    T mask(1);
  111.  
  112.    // prevedeni x na bity
  113.    for ( std::size_t i = 0; i != max_bits ; ++i )
  114.    {
  115.       buff[max_bits - 1 - i] = (x & mask) ? 1 : 0;
  116.       mask <<= 1;  // posuneme masku o 1 pozici na nizsi bit
  117.    }
  118.  
  119.    // vypis
  120.    for ( std::size_t i = 0; i != max_bits ; ++i )
  121.    {
  122.       if ( !(os << buff[i]) )
  123.       {
  124.          break;   // neco je spatne s 'os', prerusit smycku
  125.       }
  126.    }
  127.    return os;
  128. }
  129.  
  130. //---------------------------------------------------------------------------
  131. //
  132. //  priklady pouziti
  133. //
  134. //---------------------------------------------------------------------------
  135.  
  136. int main()
  137. {
  138.     
  139.    // nejdrive si pripravime kontejnery
  140.    const int N = 9;
  141.    int pole[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
  142.  
  143.    // a ted STL kontejnery
  144.    // tohle uz umime: cisla1 se inicializuji prvky pole 'pole'
  145.    std::vector<int> cisla1(pole, pole + N);
  146.  
  147.    // cisla2 se inicializuje prvky pole 'pole', ale pozpatku
  148.    // specielne kvuli Microsoft Visual C++ .NET 7.0 (beta2) to musim napsat takto
  149.    std::vector<int> cisla2;
  150.    for ( int i = 0; i < N; ++i )
  151.    {
  152.       cisla2.push_back(pole[N - 1 - i]);
  153.    }
  154.    // elegantnejsi reseni pomoci reverse_iterator v MVC7 neprojde...
  155.  
  156.    // tohle je take nove: N prvku, kazdy nula
  157.    std::vector<int> cisla3(N, 0);
  158.  
  159.    // vypiseme si je na obrazovku,
  160.    std::cout << "cisla1 : ";
  161.    std::copy(cisla1.begin(), cisla1.end(), std::ostream_iterator<int>(std::cout, "  "));
  162.    std::cout << "\n"
  163.                 "cisla2 : ";
  164.    std::copy(cisla2.begin(), cisla2.end(), std::ostream_iterator<int>(std::cout, "  "));
  165.    std::cout << "\n"
  166.                 "cisla3 : ";
  167.    std::copy(cisla3.begin(), cisla3.end(), std::ostream_iterator<int>(std::cout, "  "));
  168.    std::cout << std::endl;
  169.  
  170. //*******************************************************************
  171.    // a ted provedeme toto : cisla3 = NEG cisla1
  172.    //
  173.    std::transform(cisla1.begin(), cisla1.end(), cisla3.begin(), bitwise_not<int>());
  174. //*******************************************************************
  175.  
  176.    // vypiseme si je na obrazovku,
  177.    std::cout << "NOT cisla1 : ";
  178.    std::copy(cisla3.begin(), cisla3.end(), std::ostream_iterator<int>(std::cout, "  "));
  179.    // posledni prvky vypiseme po bitech, aby bylo zrejme, ze se to povedlo
  180.    std::cout << "\n"
  181.                 "cisla1[N-1]     : ";
  182.    write_bits(std::cout, *(cisla1.end() - 1));   // o iteratorech podrobneji
  183.    std::cout << "\n"                             // az nekdy priste
  184.                 "NOT cisla1[N-1] : ";
  185.    write_bits(std::cout, *(cisla3.end() - 1));
  186.    std::cout << std::endl;
  187.  
  188. //*******************************************************************
  189.    // a ted provedeme toto : cisla3 = cisla1 AND cisla2
  190.    //
  191.    std::transform(cisla1.begin(), cisla1.end(), cisla2.begin(), cisla3.begin(), bitwise_and<int>());
  192. //*******************************************************************
  193.  
  194.    // vypiseme si je na obrazovku,
  195.    std::cout << "cisla1 AND cisla2 : ";
  196.    std::copy(cisla3.begin(), cisla3.end(), std::ostream_iterator<int>(std::cout, "  "));
  197.    // posledni prvky vypiseme po bitech, aby bylo zrejme, ze se to povedlo
  198.    std::cout << "\n"
  199.                 "cisla1[N-1]                 : ";
  200.    write_bits(std::cout, *(cisla1.end() - 1));
  201.    std::cout << "\n"
  202.                 "cisla2[N-1]                 : ";
  203.    write_bits(std::cout, *(cisla2.end() - 1));
  204.    std::cout << "\n"
  205.                 "cisla1[N-1] AND cisla2[N-1] : ";
  206.    write_bits(std::cout, *(cisla3.end() - 1));
  207.    std::cout << std::endl;
  208.  
  209. //*******************************************************************
  210.    // a ted provedeme toto : cisla3 = cisla1 OR cisla2
  211.    //
  212.    std::transform(cisla1.begin(), cisla1.end(), cisla2.begin(), cisla3.begin(), bitwise_or<int>());
  213. //*******************************************************************
  214.  
  215.    // vypiseme si je na obrazovku,
  216.    std::cout << "cisla1 OR cisla2 : ";
  217.    std::copy(cisla3.begin(), cisla3.end(), std::ostream_iterator<int>(std::cout, "  "));
  218.    // posledni prvky vypiseme po bitech, aby bylo zrejme, ze se to povedlo
  219.    std::cout << "\n"
  220.                 "cisla1[N-1]                : ";
  221.    write_bits(std::cout, *(cisla1.end() - 1));
  222.    std::cout << "\n"
  223.                 "cisla2[N-1]                : ";
  224.    write_bits(std::cout, *(cisla2.end() - 1));
  225.    std::cout << "\n"
  226.                 "cisla1[N-1] OR cisla2[N-1] : ";
  227.    write_bits(std::cout, *(cisla3.end() - 1));
  228.    std::cout << std::endl;
  229.  
  230. //*******************************************************************
  231.    // a ted provedeme toto : cisla3 = cisla1 XOR cisla2
  232.    //
  233.    std::transform(cisla1.begin(), cisla1.end(), cisla2.begin(), cisla3.begin(), bitwise_xor<int>());
  234. //*******************************************************************
  235.  
  236.    // vypiseme si je na obrazovku,
  237.    std::cout << "cisla1 XOR cisla2 : ";
  238.    std::copy(cisla3.begin(), cisla3.end(), std::ostream_iterator<int>(std::cout, "  "));
  239.    // posledni prvky vypiseme po bitech, aby bylo zrejme, ze se to povedlo
  240.    std::cout << "\n"
  241.                 "cisla1[N-1]                 : ";
  242.    write_bits(std::cout, *(cisla1.end() - 1));
  243.    std::cout << "\n"
  244.                 "cisla2[N-1]                 : ";
  245.    write_bits(std::cout, *(cisla2.end() - 1));
  246.    std::cout << "\n"
  247.                 "cisla1[N-1] XOR cisla2[N-1] : ";
  248.    write_bits(std::cout, *(cisla3.end() - 1));
  249.    std::cout << std::endl;
  250.  
  251.    // spravne vysledky si jiste dokazete overit sami
  252.  
  253.    return 0;
  254. }
  255. //---------------------------------------------------------------------------
  256.