// @(#)root/cont:$Id$
// Author: Philippe Canal 05/02/01

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#ifndef ROOT_TBits
#define ROOT_TBits

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TBits                                                                //
//                                                                      //
// Container of bits.                                                   //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#ifndef ROOT_TObject
#include "TObject.h"
#endif
#ifndef ROOT_Riosfwd
#include "Riosfwd.h"
#endif
#ifndef __CINT__
#include <string.h>
#endif

class TBits : public TObject {

protected:

   UInt_t   fNbits;         // Highest bit set + 1
   UInt_t   fNbytes;        // Number of UChars in fAllBits
   UChar_t *fAllBits;       //[fNbytes] array of UChars

   void ReserveBytes(UInt_t nbytes);
   void DoAndEqual(const TBits& rhs);
   void DoOrEqual (const TBits& rhs);
   void DoXorEqual(const TBits& rhs);
   void DoLeftShift(UInt_t shift);
   void DoRightShift(UInt_t shift);
   void DoFlip();

public:
   TBits(UInt_t nbits = 8);
   TBits(const TBits&);
   TBits& operator=(const TBits&);
   virtual ~TBits();

   class TReference {
      friend class TBits;

      TBits  &fBits; //!
      UInt_t  fPos;  //!

      TReference(); // left undefined

public:
      TReference(TBits& bit, UInt_t pos) : fBits(bit),fPos(pos) { }
      ~TReference() { }

       // For b[i] = val;
      TReference& operator=(Bool_t val);

      // For b[i] = b[__j];
      TReference& operator=(const TReference& rhs);

#ifndef __CINT__
      // Flips the bit
      Bool_t operator~() const;
#endif

      // For val = b[i];
      operator Bool_t() const;
   };

   //----- bit manipulation
   //----- (note the difference with TObject's bit manipulations)
   void   ResetAllBits(Bool_t value=kFALSE);  // if value=1 set all bits to 1
   void   ResetBitNumber(UInt_t bitnumber);
   void   SetBitNumber(UInt_t bitnumber, Bool_t value = kTRUE);
   Bool_t TestBitNumber(UInt_t bitnumber) const;

   //----- Accessors and operator
   TBits::TReference operator[](UInt_t bitnumber) { return TReference(*this,bitnumber); }
   Bool_t operator[](UInt_t bitnumber) const;

   TBits& operator&=(const TBits& rhs) { DoAndEqual(rhs); return *this; }
   TBits& operator|=(const TBits& rhs) {  DoOrEqual(rhs); return *this; }
   TBits& operator^=(const TBits& rhs) { DoXorEqual(rhs); return *this; }
   TBits& operator<<=(UInt_t rhs) { DoLeftShift(rhs); return *this; }
   TBits& operator>>=(UInt_t rhs) { DoRightShift(rhs); return *this; }
   TBits  operator<<(UInt_t rhs) { return TBits(*this)<<= rhs; }
   TBits  operator>>(UInt_t rhs) { return TBits(*this)>>= rhs; }
   TBits  operator~() { TBits res(*this); res.DoFlip(); return res; }

   //----- Optimized setters
   // Each of these will replace the contents of the receiver with the bitvector
   // in the parameter array.  The number of bits is changed to nbits.  If nbits
   // is smaller than fNbits, the receiver will NOT be compacted.
   void   Set(UInt_t nbits, const Char_t *array);
   void   Set(UInt_t nbits, const UChar_t *array) { Set(nbits, (const Char_t*)array); }
   void   Set(UInt_t nbits, const Short_t *array);
   void   Set(UInt_t nbits, const UShort_t *array) { Set(nbits, (const Short_t*)array); }
   void   Set(UInt_t nbits, const Int_t *array);
   void   Set(UInt_t nbits, const UInt_t *array) { Set(nbits, (const Int_t*)array); }
   void   Set(UInt_t nbits, const Long64_t *array);
   void   Set(UInt_t nbits, const ULong64_t *array) { Set(nbits, (const Long64_t*)array); }

   //----- Optimized getters
   // Each of these will replace the contents of the parameter array with the
   // bits in the receiver.  The parameter array must be large enough to hold
   // all of the bits in the receiver.
   // Note on semantics: any bits in the parameter array that go beyond the
   // number of the bits in the receiver will have an unspecified value.  For
   // example, if you call Get(Int*) with an array of one integer and the TBits
   // object has less than 32 bits, then the remaining bits in the integer will
   // have an unspecified value.
   void   Get(Char_t *array) const;
   void   Get(UChar_t *array) const { Get((Char_t*)array); }
   void   Get(Short_t *array) const;
   void   Get(UShort_t *array) const { Get((Short_t*)array); }
   void   Get(Int_t *array) const;
   void   Get(UInt_t *array) const { Get((Int_t*)array); }
   void   Get(Long64_t *array) const;
   void   Get(ULong64_t *array) const { Get((Long64_t*)array); }

   //----- Utilities
   void    Clear(Option_t *option="");
   void    Compact();               // Reduce the space used.
   UInt_t  CountBits(UInt_t startBit=0)     const ;  // return number of bits set to 1
   UInt_t  FirstNullBit(UInt_t startBit=0)  const;
   UInt_t  FirstSetBit(UInt_t startBit=0)   const;
   UInt_t  LastNullBit(UInt_t startBit=999999999) const;
   UInt_t  LastSetBit(UInt_t startBit=999999999)  const;
   UInt_t  GetNbits()      const { return fNbits; }
   UInt_t  GetNbytes()     const { return fNbytes; }

   Bool_t  operator==(const TBits &other) const;
   Bool_t  operator!=(const TBits &other) const { return !(*this==other); }

   void    Paint(Option_t *option="");        // to visualize the bits array as an histogram, etc
   void    Print(Option_t *option="") const;  // to show the list of active bits
   void    Output(std::ostream &) const;

   ClassDef(TBits,1)        // Bit container
};


inline Bool_t operator&(const TBits::TReference& lhs, const TBits::TReference& rhs)
{
   return (Bool_t)lhs & rhs;
}

inline Bool_t operator|(const TBits::TReference& lhs, const TBits::TReference& rhs)
{
   return (Bool_t)lhs | rhs;
}

inline Bool_t operator^(const TBits::TReference& lhs, const TBits::TReference& rhs)
{
   return (Bool_t)lhs ^ rhs;
}

inline TBits operator&(const TBits& lhs, const TBits& rhs)
{
   TBits result(lhs);
   result &= rhs;
   return result;
}

inline TBits operator|(const TBits& lhs, const TBits& rhs)
{
   TBits result(lhs);
   result |= rhs;
   return result;
}

inline TBits operator^(const TBits& lhs, const TBits& rhs)
{
   TBits result(lhs);
   result ^= rhs;
   return result;
}

inline std::ostream &operator<<(std::ostream& os, const TBits& rhs)
{
   rhs.Output(os); return os;
}

// inline functions...

inline void TBits::SetBitNumber(UInt_t bitnumber, Bool_t value)
{
   // Set bit number 'bitnumber' to be value

   if (bitnumber >= fNbits) {
      UInt_t new_size = (bitnumber/8) + 1;
      if (new_size > fNbytes) {
         new_size *= 2;
         UChar_t *old_location = fAllBits;
         fAllBits = new UChar_t[new_size];
         memcpy(fAllBits,old_location,fNbytes);
         memset(fAllBits+fNbytes ,0, new_size-fNbytes);
         fNbytes = new_size;
         delete [] old_location;
      }
      fNbits = bitnumber+1;
   }
   UInt_t  loc = bitnumber/8;
   UChar_t bit = bitnumber%8;
   if (value)
      fAllBits[loc] |= (1<<bit);
   else
      fAllBits[loc] &= (0xFF ^ (1<<bit));
}

inline Bool_t TBits::TestBitNumber(UInt_t bitnumber) const
{
   // Return the current value of the bit

   if (bitnumber >= fNbits) return kFALSE;
   UInt_t  loc = bitnumber/8;
   UChar_t value = fAllBits[loc];
   UChar_t bit = bitnumber%8;
   Bool_t  result = (value & (1<<bit)) != 0;
   return result;
   // short: return 0 != (fAllBits[bitnumber/8] & (1<< (bitnumber%8)));
}

inline void TBits::ResetBitNumber(UInt_t bitnumber)
{
   SetBitNumber(bitnumber,kFALSE);
}

inline Bool_t TBits::operator[](UInt_t bitnumber) const
{
   return TestBitNumber(bitnumber);
}

inline TBits::TReference& TBits::TReference::operator=(Bool_t val)
{
   // For b[i] = val.

   fBits.SetBitNumber(fPos,val); return *this;
}

inline TBits::TReference& TBits::TReference::operator=(const TReference& rhs)
{
   // For b[i] = b[__j].

   fBits.SetBitNumber(fPos,rhs.fBits.TestBitNumber(rhs.fPos)); return *this;
}

#ifndef __CINT__
inline Bool_t TBits::TReference::operator~() const
{
   // Flips the bit.

   return !fBits.TestBitNumber(fPos);
}
#endif

inline TBits::TReference::operator Bool_t() const
{
   // For val = b[i].

   return fBits.TestBitNumber(fPos);
}

#endif


 TBits.h:1
 TBits.h:2
 TBits.h:3
 TBits.h:4
 TBits.h:5
 TBits.h:6
 TBits.h:7
 TBits.h:8
 TBits.h:9
 TBits.h:10
 TBits.h:11
 TBits.h:12
 TBits.h:13
 TBits.h:14
 TBits.h:15
 TBits.h:16
 TBits.h:17
 TBits.h:18
 TBits.h:19
 TBits.h:20
 TBits.h:21
 TBits.h:22
 TBits.h:23
 TBits.h:24
 TBits.h:25
 TBits.h:26
 TBits.h:27
 TBits.h:28
 TBits.h:29
 TBits.h:30
 TBits.h:31
 TBits.h:32
 TBits.h:33
 TBits.h:34
 TBits.h:35
 TBits.h:36
 TBits.h:37
 TBits.h:38
 TBits.h:39
 TBits.h:40
 TBits.h:41
 TBits.h:42
 TBits.h:43
 TBits.h:44
 TBits.h:45
 TBits.h:46
 TBits.h:47
 TBits.h:48
 TBits.h:49
 TBits.h:50
 TBits.h:51
 TBits.h:52
 TBits.h:53
 TBits.h:54
 TBits.h:55
 TBits.h:56
 TBits.h:57
 TBits.h:58
 TBits.h:59
 TBits.h:60
 TBits.h:61
 TBits.h:62
 TBits.h:63
 TBits.h:64
 TBits.h:65
 TBits.h:66
 TBits.h:67
 TBits.h:68
 TBits.h:69
 TBits.h:70
 TBits.h:71
 TBits.h:72
 TBits.h:73
 TBits.h:74
 TBits.h:75
 TBits.h:76
 TBits.h:77
 TBits.h:78
 TBits.h:79
 TBits.h:80
 TBits.h:81
 TBits.h:82
 TBits.h:83
 TBits.h:84
 TBits.h:85
 TBits.h:86
 TBits.h:87
 TBits.h:88
 TBits.h:89
 TBits.h:90
 TBits.h:91
 TBits.h:92
 TBits.h:93
 TBits.h:94
 TBits.h:95
 TBits.h:96
 TBits.h:97
 TBits.h:98
 TBits.h:99
 TBits.h:100
 TBits.h:101
 TBits.h:102
 TBits.h:103
 TBits.h:104
 TBits.h:105
 TBits.h:106
 TBits.h:107
 TBits.h:108
 TBits.h:109
 TBits.h:110
 TBits.h:111
 TBits.h:112
 TBits.h:113
 TBits.h:114
 TBits.h:115
 TBits.h:116
 TBits.h:117
 TBits.h:118
 TBits.h:119
 TBits.h:120
 TBits.h:121
 TBits.h:122
 TBits.h:123
 TBits.h:124
 TBits.h:125
 TBits.h:126
 TBits.h:127
 TBits.h:128
 TBits.h:129
 TBits.h:130
 TBits.h:131
 TBits.h:132
 TBits.h:133
 TBits.h:134
 TBits.h:135
 TBits.h:136
 TBits.h:137
 TBits.h:138
 TBits.h:139
 TBits.h:140
 TBits.h:141
 TBits.h:142
 TBits.h:143
 TBits.h:144
 TBits.h:145
 TBits.h:146
 TBits.h:147
 TBits.h:148
 TBits.h:149
 TBits.h:150
 TBits.h:151
 TBits.h:152
 TBits.h:153
 TBits.h:154
 TBits.h:155
 TBits.h:156
 TBits.h:157
 TBits.h:158
 TBits.h:159
 TBits.h:160
 TBits.h:161
 TBits.h:162
 TBits.h:163
 TBits.h:164
 TBits.h:165
 TBits.h:166
 TBits.h:167
 TBits.h:168
 TBits.h:169
 TBits.h:170
 TBits.h:171
 TBits.h:172
 TBits.h:173
 TBits.h:174
 TBits.h:175
 TBits.h:176
 TBits.h:177
 TBits.h:178
 TBits.h:179
 TBits.h:180
 TBits.h:181
 TBits.h:182
 TBits.h:183
 TBits.h:184
 TBits.h:185
 TBits.h:186
 TBits.h:187
 TBits.h:188
 TBits.h:189
 TBits.h:190
 TBits.h:191
 TBits.h:192
 TBits.h:193
 TBits.h:194
 TBits.h:195
 TBits.h:196
 TBits.h:197
 TBits.h:198
 TBits.h:199
 TBits.h:200
 TBits.h:201
 TBits.h:202
 TBits.h:203
 TBits.h:204
 TBits.h:205
 TBits.h:206
 TBits.h:207
 TBits.h:208
 TBits.h:209
 TBits.h:210
 TBits.h:211
 TBits.h:212
 TBits.h:213
 TBits.h:214
 TBits.h:215
 TBits.h:216
 TBits.h:217
 TBits.h:218
 TBits.h:219
 TBits.h:220
 TBits.h:221
 TBits.h:222
 TBits.h:223
 TBits.h:224
 TBits.h:225
 TBits.h:226
 TBits.h:227
 TBits.h:228
 TBits.h:229
 TBits.h:230
 TBits.h:231
 TBits.h:232
 TBits.h:233
 TBits.h:234
 TBits.h:235
 TBits.h:236
 TBits.h:237
 TBits.h:238
 TBits.h:239
 TBits.h:240
 TBits.h:241
 TBits.h:242
 TBits.h:243
 TBits.h:244
 TBits.h:245
 TBits.h:246
 TBits.h:247
 TBits.h:248
 TBits.h:249
 TBits.h:250
 TBits.h:251
 TBits.h:252
 TBits.h:253
 TBits.h:254
 TBits.h:255
 TBits.h:256
 TBits.h:257
 TBits.h:258
 TBits.h:259
 TBits.h:260
 TBits.h:261
 TBits.h:262
 TBits.h:263
 TBits.h:264
 TBits.h:265
 TBits.h:266
 TBits.h:267
 TBits.h:268
 TBits.h:269
 TBits.h:270
 TBits.h:271
 TBits.h:272
 TBits.h:273
 TBits.h:274
 TBits.h:275
 TBits.h:276
 TBits.h:277
 TBits.h:278