/* 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 <iostream>
#include <limits>
#include <converters_basic_defs.h>
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<int&>(a)^=int(b); return a; }
inline GF2& operator-= (GF2& a, GF2 b) { reinterpret_cast<int&>(a)^=int(b); return a; }
inline GF2& operator*= (GF2& a, GF2 b) { reinterpret_cast<int&>(a)&=int(b); return a; }
inline GF2& operator/= (GF2& a, GF2 b) { reinterpret_cast<int&>(a)/=int(b); return a; }
template <typename Traits> inline
std::basic_istream<char, Traits>&
operator>> (std::basic_istream<char, Traits>& is, GF2& a)
{
return is >> reinterpret_cast<int&>(a);
}
template <typename Traits> inline
std::basic_ostream<char, Traits>&
operator<< (std::basic_ostream<char, Traits>& os, GF2 a)
{
return os << int(a);
}
template <typename T, bool _is_integer=std::numeric_limits<T>::is_integer>
struct conv_to_GF2;
template <typename T>
struct conv_to_GF2<T, true> {
typedef T argument_type;
typedef polymake::topaz::GF2 result_type;
result_type operator() (typename pm::function_argument<T>::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 <typename Traits> friend
std::basic_istream<char, Traits>& operator>> (std::basic_istream<char, Traits>& is, GF2& a)
{
is >> a.value;
a.value %= 2;
return is;
}
template <typename Traits> friend
std::basic_istream<char, Traits>& operator<< (std::basic_istream<char, Traits>& 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<polymake::topaz::GF2> : numeric_limits<unsigned int> {
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 <typename T>
struct conv<T, polymake::topaz::GF2> : polymake::topaz::conv_to_GF2<T> { };
}
#endif // !USE_ENUM
#endif // _POLYMAKE_FINITE_FIELDS_H
// Local Variables:
// mode:C++
// c-basic-offset:3
// End:
syntax highlighted by Code2HTML, v. 0.9.1