M4RI  1.0.1
wordwrapper.h
Go to the documentation of this file.
1 
13 /******************************************************************************
14 *
15 * M4RI: Linear Algebra over GF(2)
16 *
17 * Copyright (C) 2011 Carlo Wood <carlo@alinoe.com>
18 *
19 * Distributed under the terms of the GNU General Public License (GPL)
20 * version 2 or higher.
21 *
22 * This code is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25 * General Public License for more details.
26 *
27 * The full text of the GPL is available at:
28 *
29 * http://www.gnu.org/licenses/
30 ******************************************************************************/
31 
32 #ifndef M4RI_DOXYGEN
33 
34 class word
35 {
36  private:
37  bool M_initialized;
38  uint64_t M_word;
39 
40  public:
41  // Default constructor. Construct uninitialized word.
42  word(void) : M_initialized(false), M_word(0xdead12344321deadUL) { }
43  // Construct a zeroed word from the int 0.
44  word(int value) : M_initialized(true), M_word(0) { assert(value == 0); }
45  // Construct a word from a given uint64_t integer value.
46  explicit word(uint64_t value) : M_initialized(true), M_word(value) { }
47 
48  // Copy constructor.
49  word(word const& w) : M_initialized(w.M_initialized), M_word(w.M_word) { assert(M_initialized); }
50  // Destructor.
51  ~word() { M_initialized = false; M_word = 0xdeaddeaddeaddeadUL; }
52 
53  // Assignment operators.
54  word& operator=(word const& w) { assert(w.M_initialized); M_initialized = w.M_initialized; M_word = w.M_word; return *this; }
55  // Assign 0 to a word.
56  word& operator=(int value)
57  {
58  assert(value == 0); // Only 0 may be assigned.
59  M_initialized = true;
60  M_word = 0;
61  return *this;
62  }
63 
64  // Compare two words.
65  friend bool operator==(word const& w1, word const& w2) { assert(w1.M_initialized && w2.M_initialized); return w1.M_word == w2.M_word; }
66  friend bool operator!=(word const& w1, word const& w2) { assert(w1.M_initialized && w2.M_initialized); return w1.M_word != w2.M_word; }
67 
68  // Invert all bits in a word.
69  word operator~(void) const { return word(~M_word); }
70 
71  // Convert word as boolean to a mask with all zeroes (false) or all ones (true), by negating it.
72  word operator-(void) const
73  {
74  assert((M_word & ~1UL) == 0);
75  return word(-M_word);
76  }
77 
78  // Bit-wise binary operators.
79  friend word operator^(word const& w1, word const& w2) { assert(w1.M_initialized && w2.M_initialized); return word(w1.M_word ^ w2.M_word); }
80  friend word operator&(word const& w1, word const& w2) { assert(w1.M_initialized && w2.M_initialized); return word(w1.M_word & w2.M_word); }
81  friend word operator|(word const& w1, word const& w2) { assert(w1.M_initialized && w2.M_initialized); return word(w1.M_word | w2.M_word); }
82  word& operator^=(word const& w) { assert(M_initialized && w.M_initialized); M_word ^= w.M_word; return *this; }
83  word& operator&=(word const& w) { assert(M_initialized && w.M_initialized); M_word &= w.M_word; return *this; }
84  word& operator|=(word const& w) { assert(M_initialized && w.M_initialized); M_word |= w.M_word; return *this; }
85 
86  // Shift operators.
87  friend word operator<<(word const& w, size_t shift) { assert(w.M_initialized); assert(shift < 64); return word(w.M_word << shift); }
88  friend word operator<<(word const& w, int shift) { assert(w.M_initialized); assert(shift >= 0 && shift < 64); return word(w.M_word << shift); }
89  friend word operator>>(word const& w, size_t shift) { assert(w.M_initialized); assert(shift < 64); return word(w.M_word >> shift); }
90  friend word operator>>(word const& w, int shift) { assert(w.M_initialized); assert(shift >= 0 && shift < 64); return word(w.M_word >> shift); }
91  word& operator<<=(int shift) { assert(M_initialized); assert(shift >= 0 && shift < 64); M_word <<= shift; return *this; }
92  word& operator>>=(int shift) { assert(M_initialized); assert(shift >= 0 && shift < 64); M_word >>= shift; return *this; }
93 
94  // Initialize an array of words with zero.
95  static void init_array(word* const& a, wi_t size)
96  {
97  for (wi_t i = 0; i < size; ++i)
98  a[i] = 0;
99  }
100 
101  // Perform explicit conversions.
102  BIT convert_to_BIT(void) const
103  {
104  assert(M_initialized);
105  assert((M_word & ~1UL) == 0); // May only be 0 or 1.
106  return M_word;
107  }
108  int convert_to_int(void) const
109  {
110  assert(M_initialized);
111  assert(M_word <= 0x7fffffffU); // Make sure the value doesn't exceed the maximum value of an int.
112  return M_word;
113  }
114  uint64_t convert_to_uint64_t(void) const { assert(M_initialized); return M_word; }
115 
116  // NOT operator. Returns true if all bits are zero.
117  bool operator!(void) const { return !M_word; }
118  // Automatic conversion to boolean.
119  operator bool(void) const { assert(M_initialized); return M_word != 0; }
120 
121  private:
122  // Disallow conversion to int (this protects us from accidental conversion to bool (see above) and from there to int without us noticing that).
123  operator int(void) const { assert(false); return 0; }
124 };
125 
126 #define __M4RI_CONVERT_TO_BIT(w) ((w).convert_to_BIT())
127 #define __M4RI_CONVERT_TO_INT(w) ((w).convert_to_int())
128 #define __M4RI_CONVERT_TO_UINT64_T(w) ((w).convert_to_uint64_t())
129 #define __M4RI_CONVERT_TO_WORD(i) word((uint64_t)(i))
130 
131 #endif // M4RI_DOXYGEN