Click here to Skip to main content
15,884,298 members
Articles / Programming Languages / C#
Tip/Trick

Pointer Arithmetic Utility Struct

Rate me:
Please Sign up or sign in to vote.
4.00/5 (1 vote)
3 Jul 2010CPOL 7.3K   1  
A uitility struct to assist with pointer arithmetic

Why?


A question was posted here[^] that aked a simple question about pointer aritmetic that required an equally simple anwer, but lead me to thinking that a wrapper around System.IntPtr that contains some basic arithmetic would be a useful thing to have to hand, so I knocked up this simple struct.


Disclaimer


I haven't fully tested it but due to the simplicity I can't forsee any major issues. If you come across any then let me know and I'll address them.


The Code


So here it is, just copy and paste (I recommend putting it into a suitable namespace) and you should be good to go. Use it as you like, I accept no responsibility blah blah...


C#
using System;
using System.Runtime.InteropServices;
/// <summary>
/// Utility IntPtr wrapper to assist with pointer arithmetic.
/// Includes implicit conversion to IntPtr and explicit conversion from IntPtr, GCHandle etc...
/// </summary>
[Serializable]
public struct IntPointer
{
    #region Fields
    public static readonly IntPointer Zero = new IntPointer();
    /// <summary>
    /// Wrapped IntPtr.
    /// </summary>
    private IntPtr intPtr;
    #endregion
    #region Constructors
    // This contructor is called by all others!
    public IntPointer(IntPtr intPtr)
    {
        this.intPtr = intPtr;
    }
    public IntPointer(GCHandle gcHandle)
        : this(gcHandle.AddrOfPinnedObject())
    { }
    public IntPointer(int value)
        : this(new IntPtr(value))
    { }
    public IntPointer(long value)
        : this(new IntPtr(value))
    { }
    #endregion
    #region Operator Overloads
    public static bool operator ==(IntPointer intPointerA, IntPointer intPointerB)
    {
        return intPointerA.intPtr == intPointerB.intPtr;
    }
    public static bool operator !=(IntPointer intPointerA, IntPointer intPointerB)
    {
        return !(intPointerA == intPointerB);
    }
    public static IntPointer operator +(IntPointer intPointer, int value)
    {
        if (Size == 8)
            return new IntPointer((long)intPointer + value);
        return new IntPointer((int)intPointer + value);
    }
    public static IntPointer operator -(IntPointer intPointer, int value)
    {
        if (Size == 8)
            return new IntPointer((long)intPointer - value);
        return new IntPointer((int)intPointer - value);
    }
    public static IntPointer operator +(IntPointer intPointer, long value)
    {
        return new IntPointer((long)intPointer + value);
    }
    public static IntPointer operator -(IntPointer intPointer, long value)
    {
        return new IntPointer((long)intPointer - value);
    }
    public static IntPointer operator +(IntPointer intPointer, object structure)
    {
        if (Size == 8)
            return new IntPointer((long)intPointer + Marshal.SizeOf(structure));
        return new IntPointer((int)intPointer + Marshal.SizeOf(structure));
    }
    public static IntPointer operator -(IntPointer intPointer, object structure)
    {
        if (Size == 8)
            return new IntPointer((long)intPointer - Marshal.SizeOf(structure));
        return new IntPointer((int)intPointer - Marshal.SizeOf(structure));
    }
    public static IntPointer operator +(IntPointer intPointer, Type t)
    {
        if (Size == 8)
            return new IntPointer((long)intPointer + Marshal.SizeOf(t));
        return new IntPointer((int)intPointer + Marshal.SizeOf(t));
    }
    public static IntPointer operator -(IntPointer intPointer, Type t)
    {
        if (Size == 8)
            return new IntPointer((long)intPointer - Marshal.SizeOf(t));
        return new IntPointer((int)intPointer - Marshal.SizeOf(t));
    }
    public static explicit operator IntPointer(GCHandle gcHandle)
    {
        return new IntPointer(gcHandle);
    }
    public static explicit operator IntPointer(int value)
    {
        return new IntPointer(value);
    }
    public static explicit operator IntPointer(IntPtr intPtr)
    {
        return new IntPointer(intPtr);
    }
    public static explicit operator IntPointer(long value)
    {
        return new IntPointer(value);
    }
    public static explicit operator int(IntPointer value)
    {
        return (int)value.intPtr;
    }
    public static implicit operator IntPtr(IntPointer intPointer)
    {
        return intPointer.intPtr;
    }
    public static explicit operator long(IntPointer value)
    {
        return (long)value.intPtr;
    }
    #endregion
    #region Properties
    public IntPtr IntPtr
    {
        get { return intPtr; }
    }
    public static int Size
    {
        get { return IntPtr.Size; }
    }
    #endregion
    #region Methods
    public override bool Equals(object obj)
    {
        if (obj is IntPointer && (IntPointer)obj == this)
            return true;
        if (obj is IntPtr && (IntPtr)obj == this.intPtr)
            return true;
        return false;
    }
    public override int GetHashCode()
    {
        return intPtr.GetHashCode();
    }
    public IntPointer Offset(object structure, int count)
    {
        if (Size == 8)
            return new IntPointer((long)this + (Marshal.SizeOf(structure) * count));
        return new IntPointer((int)this + (Marshal.SizeOf(structure) * count));
    }
    public IntPointer Offset(Type t, int count)
    {
        if (Size == 8)
            return new IntPointer((long)this + (Marshal.SizeOf(t) * count));
        return new IntPointer((int)this + (Marshal.SizeOf(t) * count));
    }
    public int ToInt32()
    {
        return intPtr.ToInt32();
    }
    public long ToInt64()
    {
        return intPtr.ToInt64();
    }
    public override string ToString()
    {
        return intPtr.ToString();
    }
    public string ToString(string format)
    {
        return intPtr.ToString(format);
    }
    #endregion
}

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
CEO Dave Meadowcroft
United Kingdom United Kingdom
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
-- There are no messages in this forum --