M4RI
1.0.1
|
00001 00013 /****************************************************************************** 00014 * 00015 * M4RI: Linear Algebra over GF(2) 00016 * 00017 * Copyright (C) 2011 Carlo Wood <carlo@alinoe.com> 00018 * 00019 * Distributed under the terms of the GNU General Public License (GPL) 00020 * version 2 or higher. 00021 * 00022 * This code is distributed in the hope that it will be useful, 00023 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00024 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00025 * General Public License for more details. 00026 * 00027 * The full text of the GPL is available at: 00028 * 00029 * http://www.gnu.org/licenses/ 00030 ******************************************************************************/ 00031 00032 #ifndef M4RI_DOXYGEN 00033 00034 class word 00035 { 00036 private: 00037 bool M_initialized; 00038 uint64_t M_word; 00039 00040 public: 00041 // Default constructor. Construct uninitialized word. 00042 word(void) : M_initialized(false), M_word(0xdead12344321deadUL) { } 00043 // Construct a zeroed word from the int 0. 00044 word(int value) : M_initialized(true), M_word(0) { assert(value == 0); } 00045 // Construct a word from a given uint64_t integer value. 00046 explicit word(uint64_t value) : M_initialized(true), M_word(value) { } 00047 00048 // Copy constructor. 00049 word(word const& w) : M_initialized(w.M_initialized), M_word(w.M_word) { assert(M_initialized); } 00050 // Destructor. 00051 ~word() { M_initialized = false; M_word = 0xdeaddeaddeaddeadUL; } 00052 00053 // Assignment operators. 00054 word& operator=(word const& w) { assert(w.M_initialized); M_initialized = w.M_initialized; M_word = w.M_word; return *this; } 00055 // Assign 0 to a word. 00056 word& operator=(int value) 00057 { 00058 assert(value == 0); // Only 0 may be assigned. 00059 M_initialized = true; 00060 M_word = 0; 00061 return *this; 00062 } 00063 00064 // Compare two words. 00065 friend bool operator==(word const& w1, word const& w2) { assert(w1.M_initialized && w2.M_initialized); return w1.M_word == w2.M_word; } 00066 friend bool operator!=(word const& w1, word const& w2) { assert(w1.M_initialized && w2.M_initialized); return w1.M_word != w2.M_word; } 00067 00068 // Invert all bits in a word. 00069 word operator~(void) const { return word(~M_word); } 00070 00071 // Convert word as boolean to a mask with all zeroes (false) or all ones (true), by negating it. 00072 word operator-(void) const 00073 { 00074 assert((M_word & ~1UL) == 0); 00075 return word(-M_word); 00076 } 00077 00078 // Bit-wise binary operators. 00079 friend word operator^(word const& w1, word const& w2) { assert(w1.M_initialized && w2.M_initialized); return word(w1.M_word ^ w2.M_word); } 00080 friend word operator&(word const& w1, word const& w2) { assert(w1.M_initialized && w2.M_initialized); return word(w1.M_word & w2.M_word); } 00081 friend word operator|(word const& w1, word const& w2) { assert(w1.M_initialized && w2.M_initialized); return word(w1.M_word | w2.M_word); } 00082 word& operator^=(word const& w) { assert(M_initialized && w.M_initialized); M_word ^= w.M_word; return *this; } 00083 word& operator&=(word const& w) { assert(M_initialized && w.M_initialized); M_word &= w.M_word; return *this; } 00084 word& operator|=(word const& w) { assert(M_initialized && w.M_initialized); M_word |= w.M_word; return *this; } 00085 00086 // Shift operators. 00087 friend word operator<<(word const& w, size_t shift) { assert(w.M_initialized); assert(shift < 64); return word(w.M_word << shift); } 00088 friend word operator<<(word const& w, int shift) { assert(w.M_initialized); assert(shift >= 0 && shift < 64); return word(w.M_word << shift); } 00089 friend word operator>>(word const& w, size_t shift) { assert(w.M_initialized); assert(shift < 64); return word(w.M_word >> shift); } 00090 friend word operator>>(word const& w, int shift) { assert(w.M_initialized); assert(shift >= 0 && shift < 64); return word(w.M_word >> shift); } 00091 word& operator<<=(int shift) { assert(M_initialized); assert(shift >= 0 && shift < 64); M_word <<= shift; return *this; } 00092 word& operator>>=(int shift) { assert(M_initialized); assert(shift >= 0 && shift < 64); M_word >>= shift; return *this; } 00093 00094 // Initialize an array of words with zero. 00095 static void init_array(word* const& a, wi_t size) 00096 { 00097 for (wi_t i = 0; i < size; ++i) 00098 a[i] = 0; 00099 } 00100 00101 // Perform explicit conversions. 00102 BIT convert_to_BIT(void) const 00103 { 00104 assert(M_initialized); 00105 assert((M_word & ~1UL) == 0); // May only be 0 or 1. 00106 return M_word; 00107 } 00108 int convert_to_int(void) const 00109 { 00110 assert(M_initialized); 00111 assert(M_word <= 0x7fffffffU); // Make sure the value doesn't exceed the maximum value of an int. 00112 return M_word; 00113 } 00114 uint64_t convert_to_uint64_t(void) const { assert(M_initialized); return M_word; } 00115 00116 // NOT operator. Returns true if all bits are zero. 00117 bool operator!(void) const { return !M_word; } 00118 // Automatic conversion to boolean. 00119 operator bool(void) const { assert(M_initialized); return M_word != 0; } 00120 00121 private: 00122 // Disallow conversion to int (this protects us from accidental conversion to bool (see above) and from there to int without us noticing that). 00123 operator int(void) const { assert(false); return 0; } 00124 }; 00125 00126 #define __M4RI_CONVERT_TO_BIT(w) ((w).convert_to_BIT()) 00127 #define __M4RI_CONVERT_TO_INT(w) ((w).convert_to_int()) 00128 #define __M4RI_CONVERT_TO_UINT64_T(w) ((w).convert_to_uint64_t()) 00129 #define __M4RI_CONVERT_TO_WORD(i) word((uint64_t)(i)) 00130 00131 #endif // M4RI_DOXYGEN