/* Copyright (c) 1997-2006 Ewgenij Gawrilow, Michael Joswig (Technische Universitaet Berlin, Germany) http://www.math.tu-berlin.de/polymake, mailto:polymake@math.tu-berlin.de This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version: http://www.gnu.org/licenses/gpl.txt. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ #ifndef _POLYMAKE_FINITE_FIELDS_H #define _POLYMAKE_FINITE_FIELDS_H "$Project: polymake $$Id: FiniteFields.h 7434 2006-09-13 21:06:19Z gawrilow $" #include #include #include namespace polymake { namespace topaz { #ifdef __INTEL_COMPILER # define _POLYMAKE_USE_ENUM 1 #elif defined(__GNUC__) # define _POLYMAKE_USE_ENUM __GNUC__>3 || (__GNUC_MINOR__ >=4 && __GNUC_PATCHLEVEL__ >= 4) #else # define _POLYMAKE_USE_ENUM 0 #endif #if _POLYMAKE_USE_ENUM enum GF2 { GF2_zero=0, GF2_one=1 }; inline GF2 operator+(GF2 x) { return x; } inline GF2 operator-(GF2 x) { return x; } inline GF2 operator+ (GF2 a, GF2 b) { return GF2(int(a)^int(b)); } inline GF2 operator- (GF2 a, GF2 b) { return GF2(int(a)^int(b)); } inline GF2 operator* (GF2 a, GF2 b) { return GF2(int(a)&int(b)); } inline GF2 operator/ (GF2 a, GF2 b) { return GF2(int(a)/int(b)); } inline GF2& operator+= (GF2& a, GF2 b) { reinterpret_cast(a)^=int(b); return a; } inline GF2& operator-= (GF2& a, GF2 b) { reinterpret_cast(a)^=int(b); return a; } inline GF2& operator*= (GF2& a, GF2 b) { reinterpret_cast(a)&=int(b); return a; } inline GF2& operator/= (GF2& a, GF2 b) { reinterpret_cast(a)/=int(b); return a; } template inline std::basic_istream& operator>> (std::basic_istream& is, GF2& a) { return is >> reinterpret_cast(a); } template inline std::basic_ostream& operator<< (std::basic_ostream& os, GF2 a) { return os << int(a); } template ::is_integer> struct conv_to_GF2; template struct conv_to_GF2 { typedef T argument_type; typedef polymake::topaz::GF2 result_type; result_type operator() (typename pm::function_argument::type x) const { return result_type(x%2); } }; #else // !USE_ENUM enum { GF2_zero=0, GF2_one=1 }; class GF2 { int value; GF2(int v, bool) : value(v) { } public: GF2() : value(0) { } GF2(int v) : value(v%2) { } const GF2& operator+ () const { return *this; } const GF2& operator- () const { return *this; } friend GF2 operator+ (const GF2& a, const GF2& b) { return GF2(a.value^b.value, true); } friend GF2 operator- (const GF2& a, const GF2& b) { return GF2(a.value^b.value, true); } friend GF2 operator* (const GF2& a, const GF2& b) { return GF2(a.value&b.value, true); } friend GF2 operator/ (const GF2& a, const GF2& b) { return GF2(a.value/b.value, true); } GF2& operator+= (GF2 b) { value^=b.value; return *this; } GF2& operator-= (GF2 b) { value^=b.value; return *this; } GF2& operator*= (GF2 b) { value&=b.value; return *this; } GF2& operator/= (GF2 b) { value/=b.value; return *this; } template friend std::basic_istream& operator>> (std::basic_istream& is, GF2& a) { is >> a.value; a.value %= 2; return is; } template friend std::basic_istream& operator<< (std::basic_istream& os, const GF2& a) { return os << a.value; } operator bool() const { return value; } }; #endif // !USE_ENUM } } // end namespace polymake::topaz namespace std { template <> struct numeric_limits : numeric_limits { static polymake::topaz::GF2 min() throw() { return polymake::topaz::GF2_zero; } static polymake::topaz::GF2 max() throw() { return polymake::topaz::GF2_one; } static const int digits=1; static const int digits10=1; }; } #if _POLYMAKE_USE_ENUM namespace pm { template struct conv : polymake::topaz::conv_to_GF2 { }; } #endif // !USE_ENUM #endif // _POLYMAKE_FINITE_FIELDS_H // Local Variables: // mode:C++ // c-basic-offset:3 // End: