--    GMPAda, binding to the Ada Language for the GNU MultiPrecision library.
--    Copyright (C) 2007-2017 Nicolas Boulenguez <nicolas.boulenguez@free.fr>
--
--    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 3 of the License, or
--    (at your option) any later version.
--
--    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.
--
--    You should have received a copy of the GNU General Public License
--    along with this program.  If not, see <http://www.gnu.org/licenses/>.

package body GNU_Multiple_Precision is

   use GMP.Binding;
   use type Interfaces.C.int;

   overriding procedure Initialize (Object : in out Big_Integer)
   is
   begin
      Mpz_Init (Object.Value);
   end Initialize;

   overriding procedure Adjust (Object : in out Big_Integer)
   is
      Temp : constant Mpz_T := Object.Value;
   begin
      Mpz_Init_Set (Object.Value, Temp);
   end Adjust;

   overriding procedure Finalize (Object : in out Big_Integer)
   is
   begin
      Mpz_Clear (Object.Value);
   end Finalize;

   overriding function "="  (Left, Right : Big_Integer) return Boolean
   is
   begin
      return Mpz_Cmp (Left.Value, Right.Value) = 0;
   end "=";

   overriding procedure Initialize (Object : in out Big_Rational)
   is
   begin
      Mpq_Init (Object.Value);
   end Initialize;

   overriding procedure Adjust (Object : in out Big_Rational)
   is
      Temp : constant Mpq_T := Object.Value;
   begin
      Mpq_Init (Object.Value);
      Mpq_Set (Object.Value, Temp);
   end Adjust;

   overriding procedure Finalize (Object : in out Big_Rational)
   is
   begin
      Mpq_Clear (Object.Value);
   end Finalize;

   overriding function "=" (Left, Right : in Big_Rational) return Boolean
   is
   begin
      return Mpq_Equal (Left.Value, Right.Value) /= 0;
   end "=";

   procedure Read (Stream : access Ada.Streams.Root_Stream_Type'Class;
                   Item   :   out  Big_Rational)
   is
      pragma Unmodified (Item);
      --  Item *is* modified, please no warning.
      --  Does anyone see how to do it in a cleaner way?
   begin
      Mpz_T'Read (Stream, Mpq_Numref (Item.Value).all);
      Mpz_T'Read (Stream, Mpq_Denref (Item.Value).all);
   end Read;

   procedure Write (Stream : access Ada.Streams.Root_Stream_Type'Class;
                    Item   : in     Big_Rational)
   is
   begin
      Mpz_T'Write (Stream, Mpq_Numref (Item.Value).all);
      Mpz_T'Write (Stream, Mpq_Denref (Item.Value).all);
   end Write;

   overriding procedure Initialize (Object : in out Big_Float)
   is
   begin
      Mpf_Init (Object.Value);
   end Initialize;

   overriding procedure Adjust (Object : in out Big_Float)
   is
      Temp : constant Mpf_T := Object.Value;
   begin
      Mpf_Init_Set (Object.Value, Temp);
   end Adjust;

   overriding procedure Finalize (Object : in out Big_Float)
   is
   begin
      Mpf_Clear (Object.Value);
   end Finalize;

   overriding function "="  (Left, Right : Big_Float) return Boolean
   is
   begin
      return Mpf_Cmp (Left.Value, Right.Value) = 0;
   end "=";

   function Identity (Item : in Character)
                     return Character
   is
   begin
      return Item;
   end Identity;

   function Identity (Item : in Character;
                      Substitute : in Character := ' ')
                     return Character is
      pragma Unreferenced (Substitute);
   begin
      return Item;
   end Identity;

end GNU_Multiple_Precision;
