M4RI 1.0.1
wordwrapper.h
Go to the documentation of this file.
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