-
Notifications
You must be signed in to change notification settings - Fork 131
/
GenericVector.cs
176 lines (162 loc) · 6.66 KB
/
GenericVector.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
using RDotNet.Dynamic;
using RDotNet.Internals;
using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Runtime.InteropServices;
using System.Security.Permissions;
namespace RDotNet
{
/// <summary>
/// A generic list. This is also known as list in R.
/// </summary>
[SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
public class GenericVector : Vector<SymbolicExpression>
{
/// <summary>
/// Creates a new empty GenericVector with the specified length.
/// </summary>
/// <param name="engine">The <see cref="REngine"/> handling this instance.</param>
/// <param name="length">The length.</param>
public GenericVector(REngine engine, int length)
: base(engine, engine.GetFunction<Rf_allocVector>()(SymbolicExpressionType.List, length))
{ }
/// <summary>
/// Creates a new GenericVector with the specified values.
/// </summary>
/// <param name="engine">The <see cref="REngine"/> handling this instance.</param>
/// <param name="list">The values.</param>
public GenericVector(REngine engine, IEnumerable<SymbolicExpression> list)
: base(engine, SymbolicExpressionType.List, list)
{ }
/// <summary>
/// Creates a new instance for a list.
/// </summary>
/// <param name="engine">The <see cref="REngine"/> handling this instance.</param>
/// <param name="coerced">The pointer to a list.</param>
protected internal GenericVector(REngine engine, IntPtr coerced)
: base(engine, coerced)
{ }
/// <summary>
/// Gets the element at the specified index.
/// </summary>
/// <remarks>Used for pre-R 3.5 </remarks>
/// <param name="index">The zero-based index of the element to get.</param>
/// <returns>The element at the specified index.</returns>
protected override SymbolicExpression GetValue(int index)
{
int offset = GetOffset(index);
IntPtr pointer = Marshal.ReadIntPtr(DataPointer, offset);
return new SymbolicExpression(Engine, pointer);
}
/// <summary>
/// Gets the element at the specified index.
/// </summary>
/// <remarks>Used for R 3.5 and higher, to account for ALTREP objects</remarks>
/// <param name="index">The zero-based index of the element to get.</param>
/// <returns>The element at the specified index.</returns>
protected override SymbolicExpression GetValueAltRep(int index)
{
return GetValue(index);
}
/// <summary>
/// Sets the element at the specified index.
/// </summary>
/// <remarks>Used for pre-R 3.5 </remarks>
/// <param name="index">The zero-based index of the element to set.</param>
/// <param name="value">The value to set</param>
protected override void SetValue(int index, SymbolicExpression value)
{
int offset = GetOffset(index);
Marshal.WriteIntPtr(DataPointer, offset, (value ?? Engine.NilValue).DangerousGetHandle());
}
/// <summary>
/// Sets the element at the specified index.
/// </summary>
/// <remarks>Used for R 3.5 and higher, to account for ALTREP objects</remarks>
/// <param name="index">The zero-based index of the element to set.</param>
/// <param name="value">The value to set</param>
protected override void SetValueAltRep(int index, SymbolicExpression value)
{
SetValue(index, value);
}
/// <summary>
/// Efficient conversion from R vector representation to the array equivalent in the CLR
/// </summary>
/// <returns>Array equivalent</returns>
protected override SymbolicExpression[] GetArrayFast()
{
var res = new SymbolicExpression[this.Length];
bool useAltRep = (Engine.Compatibility == REngine.CompatibilityMode.ALTREP);
for (int i = 0; i < res.Length; i++)
{
res[i] = (useAltRep ? GetValueAltRep(i) : GetValue(i));
}
return res;
}
/// <summary>
/// Efficient initialisation of R vector values from an array representation in the CLR
/// </summary>
protected override void SetVectorDirect(SymbolicExpression[] values)
{
bool useAltRep = (Engine.Compatibility == REngine.CompatibilityMode.ALTREP);
for (int i = 0; i < values.Length; i++)
{
if (useAltRep)
{
SetValueAltRep(i, values[i]);
}
else
{
SetValue(i, values[i]);
}
}
}
/// <summary>
/// Gets the size of each item in this vector
/// </summary>
protected override int DataSize
{
get { return Marshal.SizeOf(typeof(IntPtr)); }
}
/// <summary>
/// Converts into a <see cref="RDotNet.Pairlist"/>.
/// </summary>
/// <returns>The pairlist.</returns>
public Pairlist ToPairlist()
{
return new Pairlist(Engine, this.GetFunction<Rf_VectorToPairList>()(handle));
}
/// <summary>
/// returns a new ListDynamicMeta for this Generic Vector
/// </summary>
/// <param name="parameter"></param>
/// <returns></returns>
public override DynamicMetaObject GetMetaObject(System.Linq.Expressions.Expression parameter)
{
return new ListDynamicMeta(parameter, this);
}
/// <summary> Sets the names of the vector. </summary>
///
/// <param name="names"> A variable-length parameters list containing names.</param>
public void SetNames(params string[] names)
{
CharacterVector cv = new CharacterVector(this.Engine, names);
SetNames(cv);
}
/// <summary> Sets the names of the vector.</summary>
///
/// <exception cref="ArgumentException"> Incorrect length, not equal to vector length</exception>
///
/// <param name="names"> A variable-length parameters list containing names.</param>
public void SetNames(CharacterVector names)
{
if (names.Length != this.Length)
{
throw new ArgumentException("Names vector must be same length as list");
}
SymbolicExpression namesSymbol = Engine.GetPredefinedSymbol("R_NamesSymbol");
SetAttribute(namesSymbol, names);
}
}
}