Anonymous user
Define a primitive data type: Difference between revisions
Improved VB.NET (e.g. added missing operators); converted C# to translation of VB.NET; added explanation
(→{{header|Pascal}}: name) |
(Improved VB.NET (e.g. added missing operators); converted C# to translation of VB.NET; added explanation) |
||
Line 192:
As of February 2009 no open source libraries to do this task have been located.
=={{header|C sharp
Strictly speaking, this task is impossible in C# because a type that behaves like an integer (<code>int</code>, or <code>System.Int32</code>; <code>Integer</code> in VB.NET) must be a struct (in order to have value-type semantics), and, since C# does not allow the definition of a parameterless constructor for a struct (instead generating a default parameterless constructor that sets each of its fields to the default value for the type of the field), an instance of the struct with the forbidden value of zero can be created through that default constructor.
A way to overcome this in the type's public interface, however, is to expose the field exclusively as a property that checks whether its backing field is out of range, and, if so, returns a valid default value.
Through operator overloading, it is possible to declare types in C# with the full complement of operators available on the primitive types. The following structure attempts to mimic the behavior of the <code>int</code> type in C# on .NET Core as much as possible, including interfaces and static members, delegating as much implementation as possible to the <code>Integer</code> type itself.
<lang csharp>using System;
using System.Globalization;
struct LimitedInt : IComparable, IComparable<LimitedInt>, IConvertible, IEquatable<LimitedInt>, IFormattable
{
public static readonly LimitedInt MaxValue = new LimitedInt(MAX_VALUE);
static bool IsValidValue(int value) => value >= MIN_VALUE && value <= MAX_VALUE;
readonly int _value;
public int Value => this._value == 0 ? MIN_VALUE : this._value; // Treat the default, 0, as being the minimum value.
public LimitedInt(int value)
{
if (
throw new ArgumentOutOfRangeException(nameof(value), value, $"Value must be between {MIN_VALUE} and {MAX_VALUE}.");
this._value = value;
}
#region IComparable
public int CompareTo(object obj)
{
if (obj is LimitedInt l) return
throw new ArgumentException("Object must be of type " + nameof(LimitedInt), nameof(obj));
}
#endregion
#region IComparable<LimitedInt>
public int CompareTo(LimitedInt other) => this.Value.CompareTo(other.Value);
#endregion
#region IConvertible
public TypeCode GetTypeCode() => this.Value.GetTypeCode();
bool IConvertible.ToBoolean(IFormatProvider provider) => ((IConvertible)this.Value).ToBoolean(provider);
byte IConvertible.ToByte(IFormatProvider provider) => ((IConvertible)this.Value).ToByte(provider);
char IConvertible.ToChar(IFormatProvider provider) => ((IConvertible)this.Value).ToChar(provider);
DateTime IConvertible.ToDateTime(IFormatProvider provider) => ((IConvertible)this.Value).ToDateTime(provider);
decimal IConvertible.ToDecimal(IFormatProvider provider) => ((IConvertible)this.Value).ToDecimal(provider);
double IConvertible.ToDouble(IFormatProvider provider) => ((IConvertible)this.Value).ToDouble(provider);
short IConvertible.ToInt16(IFormatProvider provider) => ((IConvertible)this.Value).ToInt16(provider);
int IConvertible.ToInt32(IFormatProvider provider) => ((IConvertible)this.Value).ToInt32(provider);
long IConvertible.ToInt64(IFormatProvider provider) => ((IConvertible)this.Value).ToInt64(provider);
sbyte IConvertible.ToSByte(IFormatProvider provider) => ((IConvertible)this.Value).ToSByte(provider);
float IConvertible.ToSingle(IFormatProvider provider) => ((IConvertible)this.Value).ToSingle(provider);
string IConvertible.ToString(IFormatProvider provider) => this.Value.ToString(provider);
object IConvertible.ToType(Type conversionType, IFormatProvider provider) => ((IConvertible)this.Value).ToType(conversionType, provider);
ushort IConvertible.ToUInt16(IFormatProvider provider) => ((IConvertible)this.Value).ToUInt16(provider);
uint IConvertible.ToUInt32(IFormatProvider provider) => ((IConvertible)this.Value).ToUInt32(provider);
ulong IConvertible.ToUInt64(IFormatProvider provider) => ((IConvertible)this.Value).ToUInt64(provider);
#endregion
#region IEquatable<LimitedInt>
public bool Equals(LimitedInt other) => this == other;
#endregion
#region IFormattable
public string ToString(string format, IFormatProvider formatProvider) => this.Value.ToString(format, formatProvider);
#endregion
#region operators
public static bool operator ==(LimitedInt left, LimitedInt right) => left.Value == right.Value;
public static bool operator !=(LimitedInt left, LimitedInt right) => left.Value != right.Value;
public static bool operator <(LimitedInt left, LimitedInt right) => left.Value < right.Value;
public static bool operator >(LimitedInt left, LimitedInt right) => left.Value > right.Value;
public static bool operator <=(LimitedInt left, LimitedInt right) => left.Value <= right.Value;
public static bool operator >=(LimitedInt left, LimitedInt right) => left.Value >= right.Value;
public static LimitedInt operator ++(LimitedInt left) => (LimitedInt)(left.Value + 1);
public static LimitedInt operator --(LimitedInt left) => (LimitedInt)(left.Value - 1);
public static LimitedInt operator +(LimitedInt left, LimitedInt right) => (LimitedInt)(left.Value + right.Value);
public static LimitedInt operator -(LimitedInt left, LimitedInt right) => (LimitedInt)(left.Value - right.Value);
public static LimitedInt operator *(LimitedInt left, LimitedInt right) => (LimitedInt)(left.Value * right.Value);
public static LimitedInt operator /(LimitedInt left, LimitedInt right) => (LimitedInt)(left.Value / right.Value);
public static LimitedInt operator %(LimitedInt left, LimitedInt right) => (LimitedInt)(left.Value % right.Value);
public static LimitedInt operator &(LimitedInt left, LimitedInt right) => (LimitedInt)(left.Value & right.Value);
public static LimitedInt operator |(LimitedInt left, LimitedInt right) => (LimitedInt)(left.Value | right.Value);
public static LimitedInt operator ^(LimitedInt left, LimitedInt right) => (LimitedInt)(left.Value ^ right.Value);
public static LimitedInt operator ~(LimitedInt left) => (LimitedInt)~left.Value;
public static LimitedInt operator >>(LimitedInt left, int right) => (LimitedInt)(left.Value >> right);
public static LimitedInt operator <<(LimitedInt left, int right) => (LimitedInt)(left.Value << right);
public static implicit operator int(LimitedInt value) => value.Value;
public static explicit operator LimitedInt(int value)
{
return new LimitedInt(value);
}
#endregion
public bool TryFormat(Span<char> destination, out int charsWritten, ReadOnlySpan<char> format = default, IFormatProvider provider = null)
=> this.Value.TryFormat(destination, out charsWritten, format, provider);
public override int GetHashCode() => this.Value.GetHashCode();
public override bool Equals(object obj) => obj is LimitedInt l && this.Equals(l);
public override string ToString() => this.Value.ToString();
#region static methods
public static bool TryParse(ReadOnlySpan<char> s, out int result) => int.TryParse(s, out result);
public static bool TryParse(ReadOnlySpan<char> s, NumberStyles style, IFormatProvider provider, out int result) => int.TryParse(s, style, provider, out result);
public static int Parse(string s, IFormatProvider provider) => int.Parse(s, provider);
public static int Parse(string s, NumberStyles style, IFormatProvider provider) => int.Parse(s, style, provider);
public static bool TryParse(string s, NumberStyles style, IFormatProvider provider, ref int result) => int.TryParse(s, style, provider, out result);
public static int Parse(string s) => int.Parse(s);
public static int Parse(string s, NumberStyles style) => int.Parse(s, style);
public static int Parse(ReadOnlySpan<char> s, NumberStyles style = NumberStyles.Integer, IFormatProvider provider = null) => int.Parse(s, style, provider);
public static bool TryParse(string s, ref int result) => int.TryParse(s, out result);
#endregion
}</lang>
Line 2,285 ⟶ 2,380:
=={{header|Visual Basic .NET}}==
See [[#C#|C#]] for why this task ''technically'' impossible in VB.NET.
Through operator overloading, it is possible to declare types in VB.NET with the full complement of operators available on the primitive types. The following structure attempts to mimic the behavior of the <code>Integer</code> type in VB.NET on .NET Core as much as possible, including interfaces and static members, delegating as much implementation as possible to the <code>Integer</code> type itself.
<lang vbnet>Structure LimitedInt
Implements IComparable, IComparable(Of LimitedInt), IConvertible, IEquatable(Of LimitedInt), IFormattable
Private Const MIN_VALUE = 1
Private Const MAX_VALUE = 10
Shared ReadOnly MinValue As New LimitedInt(MIN_VALUE)
Shared ReadOnly MaxValue As New LimitedInt(MAX_VALUE)
Private ReadOnly _value As Integer
' Treat the default, 0, as being the minimum value.
Return If(Me._value = 0, MIN_VALUE, Me._value)
End
If Not IsValidValue(value) Then Throw New ArgumentOutOfRangeException(NameOf(value), value, $"Value must be between {MIN_VALUE} and {MAX_VALUE}.")
Me._value = value
End Sub
#Region "IComparable"
Function CompareTo(obj As Object) As Integer Implements IComparable.CompareTo
If TypeOf obj IsNot LimitedInt Then Throw New ArgumentException("Object must be of type " + NameOf(LimitedInt), NameOf(obj))
Return Me.CompareTo(DirectCast(obj, LimitedInt))
End Function
#End Region
#Region "IComparable(Of LimitedInt)"
Function CompareTo(other As LimitedInt) As Integer Implements IComparable(Of LimitedInt).CompareTo
Return Me.Value.CompareTo(other.Value)
End Function
#End Region
#Region "IConvertible"
Function GetTypeCode() As TypeCode Implements IConvertible.GetTypeCode
Return Me.Value.GetTypeCode()
End Function
Private Function ToBoolean(provider As IFormatProvider) As Boolean Implements IConvertible.ToBoolean
Return DirectCast(Me.Value, IConvertible).ToBoolean(provider)
Private Function ToByte(provider As IFormatProvider) As Byte Implements IConvertible.ToByte
Private Function ToChar(provider As IFormatProvider) As Char Implements IConvertible.ToChar
Private Function ToDateTime(provider As IFormatProvider) As Date Implements IConvertible.ToDateTime
Return
End
Private Function ToDecimal(provider As IFormatProvider) As Decimal Implements IConvertible.ToDecimal
Return DirectCast(Me.Value, IConvertible).ToDecimal(provider)
Private Function ToDouble(provider As IFormatProvider) As Double Implements IConvertible.ToDouble
Private Function ToInt16(provider As IFormatProvider) As Short Implements IConvertible.ToInt16
Private Function ToInt32(provider As IFormatProvider) As Integer Implements IConvertible.ToInt32
Private Function ToInt64(provider As IFormatProvider) As Long Implements IConvertible.ToInt64
Private Function ToSByte(provider As IFormatProvider) As SByte Implements IConvertible.ToSByte
Return
End
Private Function ToSingle(provider As IFormatProvider) As Single Implements IConvertible.ToSingle
Return
End
Private Overloads Function ToString(provider As IFormatProvider) As String Implements IConvertible.ToString
End
Private Function ToType(conversionType As Type, provider As IFormatProvider) As Object Implements IConvertible.ToType
Return
End
Private Function ToUInt16(provider As IFormatProvider) As UShort Implements IConvertible.ToUInt16
Return
End
Private Function ToUInt32(provider As IFormatProvider) As UInteger Implements IConvertible.ToUInt32
Return
End
Private Function ToUInt64(provider As IFormatProvider) As ULong Implements IConvertible.ToUInt64
Return
End
#End Region
#Region "IEquatable(Of LimitedInt)"
Overloads Function Equals(other As LimitedInt) As Boolean Implements IEquatable(Of LimitedInt).Equals
Return Me = other
End Function
#End Region
#Region "IFormattable"
Private Overloads Function ToString(format As String, formatProvider As IFormatProvider) As String Implements IFormattable.ToString
Return Me.Value.ToString(format, formatProvider)
End Function
#End Region
#Region "Operators"
Shared Operator =(left As LimitedInt, right As LimitedInt) As Boolean
Return left.Value = right.Value
End Operator
Shared Operator <>(left As LimitedInt, right As LimitedInt) As Boolean
Return left.Value <> right.Value
End Operator
Shared Operator <(left As LimitedInt, right As LimitedInt) As Boolean
Return left.Value < right.Value
End Operator
Shared Operator >(left As LimitedInt, right As LimitedInt) As Boolean
Return left.Value > right.Value
End Operator
Shared Operator <=(left As LimitedInt, right As LimitedInt) As Boolean
Return left.Value <= right.Value
End Operator
Shared Operator >=(left As LimitedInt, right As LimitedInt) As Boolean
Return left.Value >= right.Value
End Operator
Shared Operator +(left As LimitedInt) As LimitedInt
Return CType(+left.Value, LimitedInt)
End Operator
Shared Operator -(left As LimitedInt) As LimitedInt
Return CType(-left.Value, LimitedInt)
End Operator
Shared Operator +(left As LimitedInt, right As LimitedInt) As LimitedInt
Return CType(left.Value + right.Value, LimitedInt)
End Operator
Shared Operator -(left As LimitedInt, right As LimitedInt) As LimitedInt
Return CType(left.Value - right.Value, LimitedInt)
End Operator
Shared Operator *(left As LimitedInt, right As LimitedInt) As LimitedInt
Return CType(left.Value * right.Value, LimitedInt)
End Operator
Shared Operator /(left As LimitedInt, right As LimitedInt) As Double
Return left.Value / right.Value
End Operator
Shared Operator \(left As LimitedInt, right As LimitedInt) As LimitedInt
Return CType(left.Value \ right.Value, LimitedInt)
End Operator
Shared Operator ^(left As LimitedInt, right As LimitedInt) As Double
Return left.Value ^ right.Value
End Operator
Shared Operator Mod(left As LimitedInt, right As LimitedInt) As LimitedInt
Return CType(left.Value Mod right.Value, LimitedInt)
End Operator
Shared Operator And(left As LimitedInt, right As LimitedInt) As LimitedInt
Return CType(left.Value And right.Value, LimitedInt)
End Operator
Shared Operator Or(left As LimitedInt, right As LimitedInt) As LimitedInt
Return CType(left.Value Or right.Value, LimitedInt)
End Operator
Shared Operator Xor(left As LimitedInt, right As LimitedInt) As LimitedInt
Return CType(left.Value Xor right.Value, LimitedInt)
End Operator
Shared Operator Not(left As LimitedInt) As LimitedInt
Return CType(Not left.Value, LimitedInt)
End Operator
Shared Operator >>(left As LimitedInt, right As Integer) As LimitedInt
Return CType(left.Value >> right, LimitedInt)
End Operator
Shared Operator <<(left As LimitedInt, right As Integer) As LimitedInt
Return CType(left.Value << right, LimitedInt)
End Operator
Shared Widening Operator CType(value As LimitedInt) As Integer
Return value.Value
End Operator
Shared Narrowing Operator CType(value As Integer) As LimitedInt
If Not IsValidValue(value) Then Throw New OverflowException()
Return New LimitedInt(value)
End Operator
#End Region
'Function TryFormat(destination As Span(Of Char), ByRef charsWritten As Integer, Optional format As ReadOnlySpan(Of Char) = Nothing, Optional provider As IFormatProvider = Nothing) As Boolean
' Return Me.Value.TryFormat(destination, charsWritten, format, provider)
'End Function
Overrides Function GetHashCode() As Integer
Return Me.Value.GetHashCode
End Function
Overrides Function Equals(obj As Object) As Boolean
Return TypeOf obj Is LimitedInt AndAlso Me.Equals(DirectCast(obj, LimitedInt))
End Function
Overrides Function ToString() As String
Return Me.Value.ToString()
End Function
#Region "Shared Methods"
'Shared Function TryParse(s As ReadOnlySpan(Of Char), ByRef result As Integer) As Boolean
' Return Integer.TryParse(s, result)
'End Function
'Shared Function TryParse(s As ReadOnlySpan(Of Char), style As Globalization.NumberStyles, provider As IFormatProvider, ByRef result As Integer) As Boolean
' Return Integer.TryParse(s, style, provider, result)
'End Function
Shared Function Parse(s As String, provider As IFormatProvider) As Integer
Return Integer.Parse(s, provider)
End Function
Shared Function Parse(s As String, style As Globalization.NumberStyles, provider As IFormatProvider) As Integer
Return Integer.Parse(s, style, provider)
End Function
Shared Function TryParse(s As String, style As Globalization.NumberStyles, provider As IFormatProvider, ByRef result As Integer) As Boolean
Return Integer.TryParse(s, style, provider, result)
End Function
Shared Function Parse(s As String) As Integer
Return Integer.Parse(s)
End Function
Shared Function Parse(s As String, style As Globalization.NumberStyles) As Integer
Return Integer.Parse(s, style)
End Function
'Shared Function Parse(s As ReadOnlySpan(Of Char), Optional style As Globalization.NumberStyles = Globalization.NumberStyles.Integer, Optional provider As IFormatProvider = Nothing) As Integer
' Return Integer.Parse(s, style, provider)
'End Function
Shared Function TryParse(s As String, ByRef result As Integer) As Boolean
Return Integer.TryParse(s, result)
End Function
#End Region
End Structure</lang>
=={{header|Visual FoxPro}}==
Visual FoxPro can't define primitives but they can be emulated with custom classes.
<lang vfp>LOCAL o As BoundedInt
o = NEWOBJECT("BoundedInt")
DO WHILE NOT o.lHasError
Line 2,462 ⟶ 2,688:
ENDIF
THIS.lHasError = .T.
ENDDEFINE
{{omit from|AWK}}
{{omit from|Axe}}
|