home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / libg++-2.7.1-bin.lha / lib / g++-include / bitdo2.h < prev    next >
C/C++ Source or Header  |  1996-10-12  |  5KB  |  185 lines

  1. #ifndef ONES
  2. #define ONES  ((_BS_word)(~0L))
  3. #endif
  4.  
  5. #ifndef DOIT_SOLID
  6. #ifdef DOIT
  7. #define DOIT_SOLID(dst, src) DOIT(dst, src, (_BS_word)(~0))
  8. #else
  9. #define DOIT_SOLID(dst, src) (dst) = (COMBINE(dst, src))
  10. #endif
  11. #endif
  12.  
  13. #ifndef DOIT
  14. #define DOIT(dst, src, mask) \
  15.   (dst) = ((COMBINE(dst, src)) & (mask)) | ((dst) & ~(mask))
  16. #endif
  17.  
  18.   _BS_word word0, mask;
  19.   int shift0, shift1;
  20.  
  21.   if (length == 0)
  22.     goto done;
  23.  
  24.   shift0 = srcbit - dstbit;
  25.  
  26.   /* First handle the case that only one destination word is touched. */
  27.   if (length + dstbit <= _BS_BITS_PER_WORD)
  28.     {
  29.       _BS_word mask
  30.     = (ONES _BS_LEFT (_BS_BITS_PER_WORD - length)) _BS_RIGHT dstbit;
  31.       _BS_word word0 = *psrc++;
  32.       if (shift0 <= 0)  /* dstbit >= srcbit */
  33.         {
  34.       word0 = word0 _BS_RIGHT (-shift0);
  35.     }
  36.       else
  37.     {
  38.       word0 = word0 _BS_LEFT shift0;
  39.       if (length + srcbit > _BS_BITS_PER_WORD)
  40.         word0 = word0 | (*psrc _BS_RIGHT (_BS_BITS_PER_WORD - shift0));
  41.     }
  42.       DOIT(*pdst, word0, mask);
  43.       goto done;
  44.     }
  45.  
  46.   /* Next optimize the case that the source and destination are aligned. */
  47.   if (shift0 == 0)
  48.     {
  49.       _BS_word mask;
  50.       if (psrc > pdst)
  51.         {
  52.       if (srcbit)
  53.         {
  54.           mask = ONES _BS_RIGHT srcbit;
  55.           DOIT(*pdst, *psrc, mask);
  56.           pdst++; psrc++;
  57.           length -= _BS_BITS_PER_WORD - srcbit;
  58.         }
  59.       for (; length >= _BS_BITS_PER_WORD; length -= _BS_BITS_PER_WORD)
  60.         {
  61.           DOIT_SOLID(*pdst, *psrc);
  62.           pdst++;  psrc++;
  63.         }
  64.       if (length)
  65.         {
  66.           mask = ONES _BS_LEFT (_BS_BITS_PER_WORD - length);
  67.           DOIT(*pdst, *psrc, mask);
  68.         }
  69.         }
  70.       else if (psrc < pdst)
  71.         {
  72.       _BS_size_t span = srcbit + length;
  73.       pdst += span / (_BS_size_t)_BS_BITS_PER_WORD;
  74.       psrc += span / (_BS_size_t)_BS_BITS_PER_WORD;
  75.       span %= (_BS_size_t)_BS_BITS_PER_WORD;
  76.       if (span)
  77.         {
  78.           mask = ONES _BS_LEFT (_BS_BITS_PER_WORD - span);
  79.           DOIT(*pdst, *psrc, mask);
  80.           length -= span;
  81.         }
  82.       pdst--;  psrc--;
  83.       for (; length >= _BS_BITS_PER_WORD; length -= _BS_BITS_PER_WORD)
  84.         {
  85.           DOIT_SOLID(*pdst, *psrc);
  86.           pdst--;  psrc--;
  87.         }
  88.       if (srcbit)
  89.         {
  90.           mask = ONES _BS_RIGHT srcbit;
  91.           DOIT(*pdst, *psrc, mask);
  92.         }
  93.     }
  94.       /* else if (psrc == pdst) --nothing to do--; */
  95.       goto done;
  96.     }
  97.  
  98.   /* Now we assume shift!=0, and more than on destination word is changed. */
  99.   if (psrc >= pdst) /* Do the updates in forward direction. */
  100.     {
  101.       _BS_word word0 = *psrc++;
  102.       _BS_word mask = ONES _BS_RIGHT dstbit;
  103.       if (shift0 > 0)
  104.         {
  105.       _BS_word word1 = *psrc++;
  106.       shift1 = _BS_BITS_PER_WORD - shift0;
  107.       DOIT(*pdst, (word0 _BS_LEFT shift0) | (word1 _BS_RIGHT shift1), mask);
  108.       word0 = word1;
  109.         }
  110.       else /* dstbit > srcbit */
  111.         {
  112.       shift1 = -shift0;
  113.       shift0 += _BS_BITS_PER_WORD;
  114.       DOIT(*pdst, word0 _BS_RIGHT shift1, mask);
  115.       }
  116.       pdst++;
  117.       length -= _BS_BITS_PER_WORD - dstbit;
  118.  
  119.       for ( ; length >= _BS_BITS_PER_WORD; length -= _BS_BITS_PER_WORD)
  120.         {
  121.       register _BS_word word1 = *psrc++;
  122.       DOIT_SOLID(*pdst,
  123.              (word0 _BS_LEFT shift0) | (word1 _BS_RIGHT shift1));
  124.       pdst++;
  125.       word0 = word1;
  126.         }
  127.       if (length > 0)
  128.         {
  129.       _BS_size_t mask = ONES _BS_LEFT (_BS_BITS_PER_WORD - length);
  130.       word0 = word0 _BS_LEFT shift0;
  131.       if (length > shift1)
  132.         word0 = word0 | (*psrc _BS_RIGHT shift1) ;
  133.       DOIT (*pdst, word0, mask);
  134.         }
  135.     }
  136.   else /* Do the updates in backward direction. */
  137.     {
  138.       _BS_word word0;
  139.  
  140.       /* Make (psrc, srcbit) and (pdst, dstbit) point to *last* bit. */
  141.       psrc += (srcbit + length  - 1) / _BS_BITS_PER_WORD;
  142.       srcbit = (srcbit + length - 1) % _BS_BITS_PER_WORD;
  143.       pdst += (dstbit + length - 1) / _BS_BITS_PER_WORD;
  144.       dstbit = (dstbit + length - 1) % _BS_BITS_PER_WORD;
  145.  
  146.       shift0 = srcbit - dstbit;
  147.  
  148.       word0 = *psrc--;
  149.       mask = ONES _BS_LEFT (_BS_BITS_PER_WORD - 1 - dstbit);
  150.       if (shift0 < 0)
  151.         {
  152.       _BS_word word1 = *psrc--;
  153.       shift1 = -shift0;
  154.       shift0 += _BS_BITS_PER_WORD;
  155.       DOIT (*pdst, (word0 _BS_RIGHT shift1) | (word1 _BS_LEFT shift0),
  156.         mask);
  157.       word0 = word1;
  158.         }
  159.       else
  160.         {
  161.       shift1 = _BS_BITS_PER_WORD - shift0;
  162.       DOIT(*pdst, word0 _BS_LEFT shift0, mask);
  163.       }
  164.       pdst--;
  165.       length -= dstbit + 1;
  166.  
  167.       for ( ; length >= _BS_BITS_PER_WORD; length -= _BS_BITS_PER_WORD)
  168.         {
  169.       register _BS_word word1 = *psrc--;
  170.       DOIT_SOLID(*pdst,
  171.              (word0 _BS_RIGHT shift1) | (word1 _BS_LEFT shift0));
  172.       pdst--;
  173.       word0 = word1;
  174.         }
  175.       if (length > 0)
  176.         {
  177.       _BS_size_t mask = ONES _BS_RIGHT (_BS_BITS_PER_WORD - length);
  178.       word0 = word0 _BS_RIGHT shift1;
  179.       if (length > shift0)
  180.         word0 = word0 | (*psrc _BS_LEFT shift0) ;
  181.       DOIT (*pdst, word0, mask);
  182.         }
  183.     }
  184.  done: ;
  185.