Skip to content

Commit a3b4da4

Browse files
committed
init
1 parent afd863c commit a3b4da4

File tree

142 files changed

+10643
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

142 files changed

+10643
-0
lines changed

.gitignore

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
*.sln
2+
Test/
3+
Debug/
4+
Release/
5+
bin/
6+
obj/
7+
Thumbs.db
8+
*.bat
9+
*.sh

Accessing/Accessing.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/* Date: 20.12.2012, Time: 17:02 */
2+
namespace IllidanS4.SharpUtils.Accessing
3+
{
4+
/// <summary>
5+
/// The interface for "get" accessors.
6+
/// </summary>
7+
public interface IReadAccessor<T>
8+
{
9+
T Value{get;}
10+
}
11+
12+
/// <summary>
13+
/// The interface for "set" accessors.
14+
/// </summary>
15+
public interface IWriteAccessor<T>
16+
{
17+
T Value{set;}
18+
}
19+
20+
/// <summary>
21+
/// The interface for both "get" and "set" accessors.
22+
/// </summary>
23+
public interface IReadWriteAccessor<T> : IReadAccessor<T>, IWriteAccessor<T>
24+
{
25+
26+
}
27+
}

Accessing/AccessorGenerator.cs

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/* Date: ‎20.12.‎2012, Time: ‏‎17:07 */
2+
using System;
3+
using System.Reflection;
4+
using System.Reflection.Emit;
5+
6+
namespace IllidanS4.SharpUtils.Accessing
7+
{
8+
/// <summary>
9+
/// Methods in this class can generate dynamic methods that can return and set a field.
10+
/// </summary>
11+
public static class AccessorGenerator
12+
{
13+
/// <summary>
14+
/// Generates a method that can set a field's value.
15+
/// </summary>
16+
/// <param name="fi">The field accessed by the method.</param>
17+
/// <param name="target">The object that contains the field, if is it not static.</param>
18+
/// <returns>The accessor procedure.</returns>
19+
public static Action<T> GenerateSetter<T>(FieldInfo fi, object target)
20+
{
21+
if(!fi.IsStatic && target == null) throw new ArgumentNullException("target", "Target can be NULL only if field is static.");
22+
if(fi.IsStatic && target != null) throw new ArgumentException("Target must be NULL if field is static.", "target");
23+
24+
Type t = TypeOf<T>.TypeID;
25+
if(!fi.FieldType.IsAssignableFrom(t)) throw new ArgumentException("Field type does not match type argument.", "T");
26+
27+
DynamicMethod setter = new DynamicMethod(
28+
"set_"+fi.Name,
29+
typeof(void),
30+
target==null?new[]{t}:new[]{target.GetType(), t},
31+
fi.DeclaringType
32+
);
33+
ILGenerator il = setter.GetILGenerator();
34+
if(target!=null)
35+
{
36+
il.Emit(OpCodes.Ldarg_0);
37+
il.Emit(OpCodes.Ldarg_1);
38+
if(t != fi.FieldType && t.IsValueType)il.Emit(OpCodes.Box, t);
39+
il.Emit(OpCodes.Stfld, fi);
40+
}else{
41+
il.Emit(OpCodes.Ldarg_0);
42+
if(t != fi.FieldType && t.IsValueType)il.Emit(OpCodes.Box, t);
43+
il.Emit(OpCodes.Stsfld, fi);
44+
}
45+
il.Emit(OpCodes.Ret);
46+
return (Action<T>)setter.CreateDelegate(TypeOf<Action<T>>.TypeID, target);
47+
}
48+
49+
/// <summary>
50+
/// Generates a method that can get a field's value.
51+
/// </summary>
52+
/// <param name="fi">The field accessed by the method.</param>
53+
/// <param name="target">The object that contains the field, if is it not static.</param>
54+
/// <returns>The accessor function.</returns>
55+
public static Func<T> GenerateGetter<T>(FieldInfo fi, object target)
56+
{
57+
if(!fi.IsStatic && target == null) throw new ArgumentNullException("target", "Target can be NULL only if field is static.");
58+
if(fi.IsStatic && target != null) throw new ArgumentException("Target must be NULL if field is static.", "target");
59+
60+
Type t = TypeOf<T>.TypeID;
61+
if(!t.IsAssignableFrom(fi.FieldType)) throw new ArgumentException("Field type does not match type argument.", "T");
62+
63+
DynamicMethod getter = new DynamicMethod(
64+
"set_"+fi.Name,
65+
t,
66+
target==null?Type.EmptyTypes:new[]{target.GetType()},
67+
fi.DeclaringType
68+
);
69+
ILGenerator il = getter.GetILGenerator();
70+
if(target!=null)
71+
{
72+
il.Emit(OpCodes.Ldarg_0);
73+
il.Emit(OpCodes.Ldfld, fi);
74+
}else{
75+
il.Emit(OpCodes.Ldsfld, fi);
76+
}
77+
if(fi.FieldType != t && fi.FieldType.IsValueType)il.Emit(OpCodes.Box, fi.FieldType);
78+
il.Emit(OpCodes.Ret);
79+
return (Func<T>)getter.CreateDelegate(TypeOf<Func<T>>.TypeID);
80+
}
81+
}
82+
}

Accessing/DefinedReadAccessor.cs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/* Date: ‎20.12.‎2012, Time: ‏‎17:02 */
2+
using System;
3+
namespace IllidanS4.SharpUtils.Accessing
4+
{
5+
/// <summary>
6+
/// Read accessor that uses a passed function that returns its value.
7+
/// </summary>
8+
public class DefinedReadAccessor<T> : IReadAccessor<T>
9+
{
10+
Func<T> getter;
11+
12+
/// <summary>
13+
/// Creates a new read accessor using a getter function.
14+
/// </summary>
15+
/// <param name="getter">The getter function that returns the current value.</param>
16+
public DefinedReadAccessor(Func<T> getter)
17+
{
18+
this.getter = getter;
19+
}
20+
21+
/// <summary>
22+
/// Creates a new read accessor using a tuple storage.
23+
/// </summary>
24+
/// <param name="tuple">The tuple storage.</param>
25+
public DefinedReadAccessor(Tuple<T> tuple) : this(()=>tuple.Item1)
26+
{
27+
28+
}
29+
30+
/// <summary>
31+
/// Creates a new read accessor using a constant value.
32+
/// </summary>
33+
/// <param name="constant">The constant value.</param>
34+
public DefinedReadAccessor(T constant) : this(()=>constant)
35+
{
36+
37+
}
38+
39+
public T Value{
40+
get{
41+
return getter();
42+
}
43+
}
44+
}
45+
}

Accessing/DefinedReadWriteAccessor.cs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/* ‎Date: 20.12.‎2012, Time: ‏‎17:01 */
2+
using System;
3+
namespace IllidanS4.SharpUtils.Accessing
4+
{
5+
/// <summary>
6+
/// Read-write accessor that uses a getter and setter method.
7+
/// </summary>
8+
public class DefinedReadWriteAccessor<T> : IReadWriteAccessor<T>
9+
{
10+
Func<T> getter;
11+
Action<T> setter;
12+
13+
public DefinedReadWriteAccessor(Func<T> getter, Action<T> setter)
14+
{
15+
this.getter = getter;
16+
this.setter = setter;
17+
}
18+
19+
public T Value{
20+
get{
21+
return getter();
22+
}
23+
set{
24+
setter(value);
25+
}
26+
}
27+
}
28+
}

Accessing/DefinedWriteAccessor.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/* Date: ‎20.12.‎2012, Time: ‏‎17:01 */
2+
using System;
3+
namespace IllidanS4.SharpUtils.Accessing
4+
{
5+
public class DefinedWriteAccessor<T> : IWriteAccessor<T>
6+
{
7+
Action<T> setter;
8+
9+
public DefinedWriteAccessor(Action<T> setter)
10+
{
11+
this.setter = setter;
12+
}
13+
14+
public T Value{
15+
set{
16+
setter(value);
17+
}
18+
}
19+
}
20+
}

Accessing/FieldAccessor.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/* Date: ‎20.12.‎2012, Time: ‏‎17:02 */
2+
using System;
3+
using System.Reflection;
4+
5+
namespace IllidanS4.SharpUtils.Accessing
6+
{
7+
public sealed class FieldAccessor<T> : IReadWriteAccessor<T>
8+
{
9+
readonly Action<T> setter;
10+
readonly Func<T> getter;
11+
12+
public FieldAccessor(FieldInfo field, object target)
13+
{
14+
if(field.FieldType != TypeOf<T>.TypeID)throw new TypeLoadException("Field is not of type "+TypeOf<T>.TypeID.ToString()+".");
15+
if(target != null && field.DeclaringType != target.GetType())throw new TypeLoadException("Target does not contain this field.");
16+
setter = AccessorGenerator.GenerateSetter<T>(field, target);
17+
getter = AccessorGenerator.GenerateGetter<T>(field, target);
18+
}
19+
20+
public T Value
21+
{
22+
get{
23+
return getter();
24+
}
25+
set{
26+
setter(value);
27+
}
28+
}
29+
}
30+
}

Accessing/IIndexable.cs

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/* Date: 30.11.2014, Time: 11:13 */
2+
using System;
3+
using System.Collections.Generic;
4+
5+
namespace IllidanS4.SharpUtils.Accessing
6+
{
7+
/// <summary>
8+
/// Represents an object which's index values can be obtained.
9+
/// </summary>
10+
public interface IIndexableGetter<TKey,TValue>
11+
{
12+
TValue this[TKey index]{
13+
get;
14+
}
15+
}
16+
17+
/// <summary>
18+
/// Represents an object which's index values can be set.
19+
/// </summary>
20+
public interface IIndexableSetter<TKey,TValue>
21+
{
22+
TValue this[TKey index]{
23+
set;
24+
}
25+
}
26+
27+
/// <summary>
28+
/// Creates an indexable wrapper around a dictionary.
29+
/// </summary>
30+
public class IndexDictionaryWrapper<TKey,TValue> : IIndexableGetter<TKey,TValue>, IIndexableSetter<TKey,TValue>
31+
{
32+
private readonly IDictionary<TKey,TValue> dict;
33+
34+
public TValue this[TKey index]
35+
{
36+
get{
37+
return dict[index];
38+
}
39+
set{
40+
dict[index] = value;
41+
}
42+
}
43+
44+
public IndexDictionaryWrapper(IDictionary<TKey,TValue> dict)
45+
{
46+
this.dict = dict;
47+
}
48+
}
49+
50+
/// <summary>
51+
/// Creates an indexable wrapper around a list.
52+
/// </summary>
53+
public class IndexListWrapper<TElement> : IIndexableGetter<int,TElement>, IIndexableSetter<int,TElement>
54+
{
55+
private readonly IList<TElement> list;
56+
57+
public TElement this[int index]
58+
{
59+
get{
60+
return list[index];
61+
}
62+
set{
63+
list[index] = value;
64+
}
65+
}
66+
67+
public IndexListWrapper(IList<TElement> list)
68+
{
69+
this.list = list;
70+
}
71+
}
72+
73+
/// <summary>
74+
/// Creates an indexable wrapper around a dynamic object.
75+
/// </summary>
76+
public class DynamicIndexWrapper<TKey,TValue> : IIndexableGetter<TKey,TValue>, IIndexableSetter<TKey,TValue>
77+
{
78+
private readonly dynamic obj;
79+
80+
public DynamicIndexWrapper(dynamic obj)
81+
{
82+
this.obj = obj;
83+
}
84+
85+
public TValue this[TKey index]
86+
{
87+
get{
88+
return obj[index];
89+
}
90+
set{
91+
obj[index] = value;
92+
}
93+
}
94+
}
95+
}

Accessing/OutputAccessor.cs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/* Date: ‎20.12.‎2012, Time: ‏‎17:00 */
2+
using System;
3+
using IllidanS4.SharpUtils.Unsafe;
4+
5+
namespace IllidanS4.SharpUtils.Accessing
6+
{
7+
public class OutputAccessor<T> : IWriteAccessor<T>
8+
{
9+
object @ref;
10+
11+
public OutputAccessor(out T value)
12+
{
13+
Extensions.Use(out value);
14+
@ref = UnsafeTools.Box(__makeref(value));
15+
}
16+
17+
public unsafe OutputAccessor(object value)
18+
{
19+
if(value == null)throw new ArgumentNullException("value");
20+
if(!(value is ValueType))throw new ArgumentException("Value can be object only if its type is a value type.", "value");
21+
if(!(value is T))throw new ArgumentException("Argument must be of type "+TypeOf<T>.TypeID.ToString()+".", "value");
22+
23+
TypedReference tr = __makeref(value);
24+
((IntPtr*)(&tr))[1] = value.GetType().TypeHandle.Value;
25+
((IntPtr*)(&tr))[0] = (**(IntPtr**)(&tr))+IntPtr.Size;
26+
27+
@ref = UnsafeTools.Box(tr);
28+
}
29+
30+
public T Value{
31+
set{
32+
__refvalue((TypedReference)@ref, T) = value;
33+
}
34+
}
35+
}
36+
}

0 commit comments

Comments
 (0)