/* Copyright (C) 2015 Alejandro Mujica (amujica en cenditel.gob.ve) José Angel Contreras (jancontreras en cenditel.gob.ve) Antonio Araujo (aaraujo en cenditel.gob.ve) Pedro Buitrago (pbuitrago en cenditel.gob.ve) CENDITEL Fundación Centro Nacional de Desarrollo e Investigación en Tecnologías Libres Este programa es software libre; Usted puede usarlo bajo los términos de la licencia de software GPL versión 2.0 de la Free Software Foundation. Este programa se distribuye con la esperanza de que sea útil, pero SIN NINGUNA GARANTÍA; tampoco las implícitas garantías de MERCANTILIDAD o ADECUACIÓN A UN PROPÓSITO PARTICULAR. Consulte la licencia GPL para más detalles. Usted debe recibir una copia de la GPL junto con este programa; si no, escriba a la Free Software Foundation Inc. 51 Franklin Street,5 Piso, Boston, MA 02110-1301, USA. */ /* Este archivo contiene la definición e implementación de una plantilla de clase para representar números enteros restringidos a un campo finito. Creado por: Alejandro J. Mujica Fecha de creación: */ # ifndef FIELDNUMBER_H # define FIELDNUMBER_H # include /** * Plantilla que representa un número restringido a un campo. * * @tparam FieldT Tipo de campo a utilizar. * * @pre FieldT debe ser base de la plantilla FiniteField. * * @see FiniteField FiniteField2. * * @author Alejandro J. Mujica (amujica en cenditel punto gob punto ve). */ template class FieldNumber { public: /// Tipo de campo que restringe al número. using FieldType = FieldT; /// Tipo de número restringido. using NumberType = typename FieldType::NumberType; private: FieldType field; NumberType value; public: /// Constructor que funge de paramétrico y por omisión. FieldNumber(const NumberType & _value = NumberType(0)); FieldNumber operator + (const FieldNumber &) const; FieldNumber & operator += (const FieldNumber &); FieldNumber operator - (const FieldNumber &) const; FieldNumber & operator -= (const FieldNumber &); FieldNumber operator * (const FieldNumber &) const; FieldNumber & operator *= (const FieldNumber &); FieldNumber operator / (const FieldNumber &) const; FieldNumber & operator /= (const FieldNumber &); bool operator == (const FieldNumber &) const; bool operator != (const FieldNumber &) const; bool operator < (const FieldNumber &) const; bool operator <= (const FieldNumber &) const; bool operator > (const FieldNumber &) const; bool operator >= (const FieldNumber &) const; bool operator ! () const; friend std::ostream & operator << (std::ostream & out, const FieldNumber & fn) { out << (NumberType) fn.value; return out; } FieldNumber & operator ++ (); FieldNumber & operator -- (); /// Operador de casting para el tipo numérico base. operator NumberType & () { return value; } }; template FieldNumber::FieldNumber(const NumberType & _value) : field(), value(field(_value)) { // Empty } template FieldNumber FieldNumber::operator + (const FieldNumber & fn) const { FieldNumber ret; ret.value = field.sum(value, fn.value); return ret; } template FieldNumber & FieldNumber::operator += (const FieldNumber & fn) { *this = *this + fn; return *this; } template FieldNumber FieldNumber::operator - (const FieldNumber & fn) const { FieldNumber ret; ret.value = field.sub(value, fn.value); return ret; } template FieldNumber & FieldNumber::operator -= (const FieldNumber & fn) { *this = *this - fn; return *this; } template FieldNumber FieldNumber::operator * (const FieldNumber & fn) const { FieldNumber ret; ret.value = field.mul(value, fn.value); return ret; } template FieldNumber & FieldNumber::operator *= (const FieldNumber & fn) { *this = *this * fn; return *this; } template FieldNumber FieldNumber::operator / (const FieldNumber & fn) const { FieldNumber ret; ret.value = field.div(value, fn.value); return ret; } template FieldNumber & FieldNumber::operator /= (const FieldNumber & fn) { *this = *this / fn; return *this; } template bool FieldNumber::operator == (const FieldNumber & fn) const { return value == fn.value; } template bool FieldNumber::operator != (const FieldNumber & fn) const { return not (*this == fn); } template bool FieldNumber::operator < (const FieldNumber & fn) const { return value < fn.value; } template bool FieldNumber::operator <= (const FieldNumber & fn) const { return value <= fn.value; } template bool FieldNumber::operator > (const FieldNumber & fn) const { return value > fn.value; } template bool FieldNumber::operator >= (const FieldNumber & fn) const { return value >= fn.value; } template bool FieldNumber::operator ! () const { return value == NumberType(0); } template FieldNumber & FieldNumber::operator ++ () { value = field.sum(value, 1); return *this; } template FieldNumber & FieldNumber::operator -- () { value = field.sub(value, 1); return *this; } # endif // FIELD_NUMBER_H