// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information.

using System;
using System.Numerics;
using System.Runtime.CompilerServices;

using Microsoft.Scripting.Runtime;

#pragma warning disable 675

namespace IronPython.Runtime.Operations {

    #region Generated FloatOps

    // *** BEGIN GENERATED CODE ***
    // generated by function: gen_float from: generate_alltypes.py

    public static partial class SingleOps {

        #region Unary Operations

        [SpecialName]
        public static Single Plus(Single x) => x;

        [SpecialName]
        public static Single Negate(Single x) => (Single)(-(x));

        [SpecialName]
        public static Single Abs(Single x) => (Single)(Math.Abs(x));

        public static bool __bool__(Single x) => (x != 0);

        public static PythonTuple __getnewargs__(Single self) => PythonTuple.MakeTuple(unchecked((double)self));

        public static object __trunc__(Single x) {
            if (x >= int.MaxValue || x <= int.MinValue) {
                return (BigInteger)x;
            } else {
                return (int)x;
            }
        }

        #endregion

        #region Binary Operations - Arithmetic

        [SpecialName]
        public static Single Add(Single x, Single y) {
            return x + y;
        }

        [SpecialName]
        public static Single Subtract(Single x, Single y) {
            return x - y;
        }

        [SpecialName]
        public static Single Multiply(Single x, Single y) {
            return x * y;
        }

        [SpecialName]
        public static Single TrueDivide(Single x, Single y) {
            if (y == 0) throw PythonOps.ZeroDivisionError();
            return x / y;
        }

        [SpecialName]
        public static Single FloorDivide(Single x, Single y) {
            if (y == 0) throw PythonOps.ZeroDivisionError();
            return (Single)Math.Floor(x / y);
        }

        #endregion

        #region Conversion operators

        [SpecialName, ExplicitConversionMethod]
        public static SByte ConvertToSByte(Single x) {
            if (SByte.MinValue <= x && x <= SByte.MaxValue) {
                return (SByte)x;
            }
            throw Converter.CannotConvertOverflow("SByte", x);
        }

        [SpecialName, ExplicitConversionMethod]
        public static Byte ConvertToByte(Single x) {
            if (Byte.MinValue <= x && x <= Byte.MaxValue) {
                return (Byte)x;
            }
            throw Converter.CannotConvertOverflow("Byte", x);
        }

        [SpecialName, ExplicitConversionMethod]
        public static Int16 ConvertToInt16(Single x) {
            if (Int16.MinValue <= x && x <= Int16.MaxValue) {
                return (Int16)x;
            }
            throw Converter.CannotConvertOverflow("Int16", x);
        }

        [SpecialName, ExplicitConversionMethod]
        public static UInt16 ConvertToUInt16(Single x) {
            if (UInt16.MinValue <= x && x <= UInt16.MaxValue) {
                return (UInt16)x;
            }
            throw Converter.CannotConvertOverflow("UInt16", x);
        }

        [SpecialName, ExplicitConversionMethod]
        public static Int32 ConvertToInt32(Single x) {
            if (Int32.MinValue <= x && x <= Int32.MaxValue) {
                return (Int32)x;
            }
            throw Converter.CannotConvertOverflow("Int32", x);
        }

        [SpecialName, ExplicitConversionMethod]
        public static UInt32 ConvertToUInt32(Single x) {
            if (UInt32.MinValue <= x && x <= UInt32.MaxValue) {
                return (UInt32)x;
            }
            throw Converter.CannotConvertOverflow("UInt32", x);
        }

        [SpecialName, ExplicitConversionMethod]
        public static Int64 ConvertToInt64(Single x) {
            if (Int64.MinValue <= x && x <= Int64.MaxValue) {
                return (Int64)x;
            }
            throw Converter.CannotConvertOverflow("Int64", x);
        }

        [SpecialName, ExplicitConversionMethod]
        public static UInt64 ConvertToUInt64(Single x) {
            if (UInt64.MinValue <= x && x <= UInt64.MaxValue) {
                return (UInt64)x;
            }
            throw Converter.CannotConvertOverflow("UInt64", x);
        }

        [SpecialName, ImplicitConversionMethod]
        public static Double ConvertToDouble(Single x) => (Double)x;

        #endregion

        #region Public API - Numerics

        [PropertyMethod, SpecialName]
        public static Single Getreal(Single x) => x;

        [PropertyMethod, SpecialName]
        public static Single Getimag(Single x) => (Single)0;

        public static Single conjugate(Single x) => x;

        #endregion
    }

    public static partial class DoubleOps {

        #region Unary Operations

        [SpecialName]
        public static Double Plus(Double x) => x;

        [SpecialName]
        public static Double Negate(Double x) => (Double)(-(x));

        [SpecialName]
        public static Double Abs(Double x) => (Double)(Math.Abs(x));

        public static bool __bool__(Double x) => (x != 0);

        public static object __trunc__(Double x) {
            if (x >= int.MaxValue || x <= int.MinValue) {
                return (BigInteger)x;
            } else {
                return (int)x;
            }
        }

        #endregion

        #region Binary Operations - Arithmetic

        [SpecialName]
        public static Double Add(Double x, Double y) {
            return x + y;
        }

        [SpecialName]
        public static Double Subtract(Double x, Double y) {
            return x - y;
        }

        [SpecialName]
        public static Double Multiply(Double x, Double y) {
            return x * y;
        }

        [SpecialName]
        public static Double TrueDivide(Double x, Double y) {
            if (y == 0) throw PythonOps.ZeroDivisionError();
            return x / y;
        }

        [SpecialName]
        public static Double FloorDivide(Double x, Double y) {
            if (y == 0) throw PythonOps.ZeroDivisionError();
            return (Double)Math.Floor(x / y);
        }

        #endregion

        #region Conversion operators

        [SpecialName, ExplicitConversionMethod]
        public static SByte ConvertToSByte(Double x) {
            if (SByte.MinValue <= x && x <= SByte.MaxValue) {
                return (SByte)x;
            }
            throw Converter.CannotConvertOverflow("SByte", x);
        }

        [SpecialName, ExplicitConversionMethod]
        public static Byte ConvertToByte(Double x) {
            if (Byte.MinValue <= x && x <= Byte.MaxValue) {
                return (Byte)x;
            }
            throw Converter.CannotConvertOverflow("Byte", x);
        }

        [SpecialName, ExplicitConversionMethod]
        public static Int16 ConvertToInt16(Double x) {
            if (Int16.MinValue <= x && x <= Int16.MaxValue) {
                return (Int16)x;
            }
            throw Converter.CannotConvertOverflow("Int16", x);
        }

        [SpecialName, ExplicitConversionMethod]
        public static UInt16 ConvertToUInt16(Double x) {
            if (UInt16.MinValue <= x && x <= UInt16.MaxValue) {
                return (UInt16)x;
            }
            throw Converter.CannotConvertOverflow("UInt16", x);
        }

        [SpecialName, ExplicitConversionMethod]
        public static Int32 ConvertToInt32(Double x) {
            if (Int32.MinValue <= x && x <= Int32.MaxValue) {
                return (Int32)x;
            }
            throw Converter.CannotConvertOverflow("Int32", x);
        }

        [SpecialName, ExplicitConversionMethod]
        public static UInt32 ConvertToUInt32(Double x) {
            if (UInt32.MinValue <= x && x <= UInt32.MaxValue) {
                return (UInt32)x;
            }
            throw Converter.CannotConvertOverflow("UInt32", x);
        }

        [SpecialName, ExplicitConversionMethod]
        public static Int64 ConvertToInt64(Double x) {
            if (Int64.MinValue <= x && x <= Int64.MaxValue) {
                return (Int64)x;
            }
            throw Converter.CannotConvertOverflow("Int64", x);
        }

        [SpecialName, ExplicitConversionMethod]
        public static UInt64 ConvertToUInt64(Double x) {
            if (UInt64.MinValue <= x && x <= UInt64.MaxValue) {
                return (UInt64)x;
            }
            throw Converter.CannotConvertOverflow("UInt64", x);
        }

        [SpecialName, ImplicitConversionMethod]
        public static Single ConvertToSingle(Double x) => (Single)x;

        #endregion

        #region Public API - Numerics

        [PropertyMethod, SpecialName]
        public static Double Getreal(Double x) => x;

        [PropertyMethod, SpecialName]
        public static Double Getimag(Double x) => (Double)0;

        public static Double conjugate(Double x) => x;

        #endregion
    }


    // *** END GENERATED CODE ***

    #endregion
}
