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