1 // Copyright 2010-2021 Google LLC
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 //     http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
14 
15 %include "ortools/base/base.i"
16 
17 %{
18 #include <vector>
19 #include "ortools/base/integral_types.h"
20 %}
21 
22 // Typemaps to represent arguments of types:
23 // - "const std::vector<TYPE>&" or
24 // - "std::vector<TYPE>"
25 // as CSHARPTYPE[].
26 // note: TYPE must be a primitive data type (PDT).
27 %define VECTOR_AS_CSHARP_ARRAY(TYPE, CTYPE, CSHARPTYPE, ARRAYTYPE)
28 // This part is for const std::vector<>&.
29 %typemap(cstype) const std::vector<TYPE>& %{ CSHARPTYPE[] %}
30 %typemap(csin)   const std::vector<TYPE>& %{ $csinput.Length, $csinput %}
31 %typemap(imtype, out="global::System.IntPtr") const std::vector<TYPE>&  %{ int length$argnum, CSHARPTYPE[] %}
32 %typemap(ctype, out="void*") const std::vector<TYPE>&  %{ int length$argnum, CTYPE* %}
33 %typemap(in)     const std::vector<TYPE>&  %{
34   $1 = new std::vector<TYPE>;
35   $1->reserve(length$argnum);
36   for(int i = 0; i < length$argnum; ++i) {
37     $1->emplace_back($input[i]);
38   }
39 %}
40 %typemap(freearg)  const std::vector<TYPE>&  { delete $1; }
41 
42 %typemap(out) const std::vector<TYPE>& %{
43   $result = new std::vector< CTYPE >((const std::vector< CTYPE> &)*$1);
44 %}
45 %typemap(csout, excode=SWIGEXCODE) const std::vector<TYPE>& {
46   global::System.IntPtr cPtr = $imcall;$excode
47   ARRAYTYPE tmpVector = null;
48   if (cPtr != global::System.IntPtr.Zero) {
49     tmpVector = new ARRAYTYPE(cPtr, true);
50     CSHARPTYPE[] outArray = new CSHARPTYPE[tmpVector.Count];
51     tmpVector.CopyTo(outArray);
52     return outArray;
53   }
54   return null;
55 }
56 // Now, we do it for std::vector<>.
57 %typemap(cstype) std::vector<TYPE> %{ CSHARPTYPE[] %}
58 %typemap(csin)   std::vector<TYPE> %{ $csinput.Length, $csinput %}
59 %typemap(imtype, out="global::System.IntPtr") std::vector<TYPE>  %{ int length$argnum, CSHARPTYPE[] %}
60 %typemap(ctype, out="void*")   std::vector<TYPE>  %{ int length$argnum, CTYPE* %}
61 %typemap(in)      std::vector<TYPE>  %{
62   $1.clear();
63   $1.reserve(length$argnum);
64   for(int i = 0; i < length$argnum; ++i) {
65     $1.emplace_back($input[i]);
66   }
67 %}
68 
69 %typemap(out) std::vector<TYPE> %{
70   $result = new std::vector< CTYPE >((const std::vector< CTYPE> &)$1);
71 %}
72 %typemap(csout, excode=SWIGEXCODE) std::vector<TYPE> {
73   global::System.IntPtr cPtr = $imcall;$excode
74   ARRAYTYPE tmpVector = null;
75   if (cPtr != global::System.IntPtr.Zero) {
76     tmpVector = new ARRAYTYPE(cPtr, true);
77     CSHARPTYPE[] outArray = new CSHARPTYPE[tmpVector.Count];
78     tmpVector.CopyTo(outArray);
79     return outArray;
80   }
81   return null;
82 }
83 %enddef // VECTOR_AS_CSHARP_ARRAY
84 
85 // Typemaps to represent arguments of types:
86 // - "const std::vector<std::vector<TYPE> >&" or
87 // - "std::vector<std::vector<TYPE> >*" or
88 // - "std::vector<std::vector<TYPE> >" or
89 // as CSHARPTYPE[][].
90 // note: TYPE must be a primitive data type (PDT).
91 %define JAGGED_MATRIX_AS_CSHARP_ARRAY(TYPE, CTYPE, CSHARPTYPE, ARRAYTYPE)
92 // This part is for const std::vector<std::vector<TYPE> >&.
93 %typemap(cstype) const std::vector<std::vector<TYPE> >&  %{ CSHARPTYPE[][] %}
94 %typemap(csin)   const std::vector<std::vector<TYPE> >&  %{
95   $csinput.GetLength(0),
96   NestedArrayHelper.GetArraySecondSize($csinput),
97   NestedArrayHelper.GetFlatArray($csinput)
98 %}
99 %typemap(imtype, out="global::System.IntPtr") const std::vector<std::vector<TYPE> >&  %{
100   int len$argnum##_1, int[] len$argnum##_2, CSHARPTYPE[]
101 %}
102 %typemap(ctype, out="void*")  const std::vector<std::vector<TYPE> >&  %{
103   int len$argnum##_1, int len$argnum##_2[], CTYPE*
104 %}
105 %typemap(in) const std::vector<std::vector<TYPE> >&  (std::vector<std::vector<TYPE> > result) %{
106   result.clear();
107   result.resize(len$argnum##_1);
108 
109   TYPE* inner_array = reinterpret_cast<TYPE*>($input);
110   int actualIndex = 0;
111   for (int index1 = 0; index1 < len$argnum##_1; ++index1) {
112     result[index1].reserve(len$argnum##_2[index1]);
113     for (int index2 = 0; index2 < len$argnum##_2[index1]; ++index2) {
114       const TYPE value = inner_array[actualIndex];
115       result[index1].emplace_back(value);
116       actualIndex++;
117     }
118   }
119 
120   $1 = &result;
121 %}
122 // Now, we do it for std::vector<std::vector<TYPE> >*.
123 %typemap(cstype) std::vector<std::vector<TYPE> >*  %{ CSHARPTYPE[][] %}
124 %typemap(csin)   std::vector<std::vector<TYPE> >*  %{
125   $csinput.GetLength(0),
126   NestedArrayHelper.GetArraySecondSize($csinput),
127   NestedArrayHelper.GetFlatArray($csinput)
128 %}
129 %typemap(imtype, out="global::System.IntPtr") std::vector<std::vector<TYPE> >*  %{
130   int len$argnum##_1, int[] len$argnum##_2, CSHARPTYPE[]
131 %}
132 %typemap(ctype, out="void*")  std::vector<std::vector<TYPE> >*  %{
133   int len$argnum##_1, int len$argnum##_2[], CTYPE*
134 %}
135 %typemap(in) std::vector<std::vector<TYPE> >*  (std::vector<std::vector<TYPE> > result) %{
136   result.clear();
137   result.resize(len$argnum##_1);
138 
139   TYPE* flat_array = reinterpret_cast<TYPE*>($input);
140   int actualIndex = 0;
141   for (int index1 = 0; index1 < len$argnum##_1; ++index1) {
142     result[index1].reserve(len$argnum##_2[index1]);
143     for (int index2 = 0; index2 < len$argnum##_2[index1]; ++index2) {
144       const TYPE value = flat_array[actualIndex];
145       result[index1].emplace_back(value);
146       actualIndex++;
147     }
148   }
149   $1 = &result;
150 %}
151 // Now, we do it for std::vector<std::vector<TYPE> >.
152 %typemap(cstype) std::vector<std::vector<TYPE> >  %{ CSHARPTYPE[][] %}
153 %typemap(csin)   std::vector<std::vector<TYPE> >  %{
154   $csinput.GetLength(0),
155   NestedArrayHelper.GetArraySecondSize($csinput),
156   NestedArrayHelper.GetFlatArray($csinput)
157 %}
158 %typemap(imtype, out="global::System.IntPtr") std::vector<std::vector<TYPE> >  %{
159   int len$argnum##_1, int[] len$argnum##_2, CSHARPTYPE[]
160 %}
161 %typemap(ctype, out="void*")  std::vector<std::vector<TYPE> >  %{
162   int len$argnum##_1, int len$argnum##_2[], CTYPE*
163 %}
164 %typemap(in) std::vector<std::vector<TYPE> > %{
165   $1.clear();
166   $1.resize(len$argnum##_1);
167 
168   TYPE* inner_array = reinterpret_cast<TYPE*>($input);
169   int actualIndex = 0;
170   for (int index1 = 0; index1 < len$argnum##_1; ++index1) {
171     $1[index1].reserve(len$argnum##_2[index1]);
172     for (int index2 = 0; index2 < len$argnum##_2[index1]; ++index2) {
173       const TYPE value = inner_array[actualIndex];
174       $1[index1].emplace_back(value);
175       actualIndex++;
176     }
177   }
178 %}
179 %enddef // JAGGED_MATRIX_AS_CSHARP_ARRAY
180 
181 // Typemaps to represent arguments of types:
182 // - "const std::vector<std::vector<TYPE> >&" or
183 // - "std::vector<std::vector<TYPE> >*" or
184 // as CSHARPTYPE[,].
185 // note: TYPE must be a primitive data type (PDT).
186 %define REGULAR_MATRIX_AS_CSHARP_ARRAY(TYPE, CTYPE, CSHARPTYPE, ARRAYTYPE)
187 // This part is for const std::vector<std::vector<>>&.
188 %typemap(cstype) const std::vector<std::vector<TYPE> >&  %{ CSHARPTYPE[,] %}
189 %typemap(csin)   const std::vector<std::vector<TYPE> >&  %{
190   $csinput.GetLength(0),
191   $csinput.GetLength(1),
192   NestedArrayHelper.GetFlatArrayFromMatrix($csinput)
193 %}
194 %typemap(imtype, out="global::System.IntPtr") const std::vector<std::vector<TYPE> >&  %{
195   int len$argnum##_1, int len$argnum##_2, CSHARPTYPE[]
196 %}
197 %typemap(ctype, out="void*")  const std::vector<std::vector<TYPE> >&  %{
198   int len$argnum##_1, int len$argnum##_2, CTYPE*
199 %}
200 %typemap(in) const std::vector<std::vector<TYPE> >&  (std::vector<std::vector<TYPE> > result) %{
201   result.clear();
202   result.resize(len$argnum##_1);
203 
204   TYPE* inner_array = reinterpret_cast<TYPE*>($input);
205   int actualIndex = 0;
206   for (int index1 = 0; index1 < len$argnum##_1; ++index1) {
207     result[index1].reserve(len$argnum##_2);
208     for (int index2 = 0; index2 < len$argnum##_2; ++index2) {
209       const TYPE value = inner_array[actualIndex];
210       result[index1].emplace_back(value);
211       actualIndex++;
212     }
213   }
214 
215   $1 = &result;
216 %}
217 // Now, we do it for std::vector<std::vector<>>*.
218 %typemap(cstype) std::vector<std::vector<TYPE> >*  %{ CSHARPTYPE[,] %}
219 %typemap(csin)   std::vector<std::vector<TYPE> >*  %{
220   $csinput.GetLength(0),
221   $csinput.GetLength(1),
222   NestedArrayHelper.GetFlatArrayFromMatrix($csinput)
223 %}
224 %typemap(imtype, out="global::System.IntPtr") std::vector<std::vector<TYPE> >*  %{
225   int len$argnum##_1, int len$argnum##_2, CSHARPTYPE[]
226 %}
227 %typemap(ctype, out="void*")  std::vector<std::vector<TYPE> >*  %{
228   int len$argnum##_1, int len$argnum##_2, CTYPE*
229 %}
230 %typemap(in) std::vector<std::vector<TYPE> >*  (std::vector<std::vector<TYPE> > result) %{
231   result.clear();
232   result.resize(len$argnum##_1);
233 
234   TYPE* flat_array = reinterpret_cast<TYPE*>($input);
235   int actualIndex = 0;
236   for (int index1 = 0; index1 < len$argnum##_1; ++index1) {
237     result[index1].reserve(len$argnum##_2);
238     for (int index2 = 0; index2 < len$argnum##_2; ++index2) {
239       const TYPE value = flat_array[actualIndex];
240       result[index1].emplace_back(value);
241       actualIndex++;
242     }
243   }
244   $1 = &result;
245 %}
246 %enddef // REGULAR_MATRIX_AS_CSHARP_ARRAY
247 
248 // SWIG Macros to use std::vector<Type> and const std::vector<Type>& in .Net as
249 // regular .Net array, where Type is an integral numeric type.
250 // see: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/integral-numeric-types
251 // By default vector<vector<Type>> is mapped to a jagged array i.e. .Net type[][]
252 // If you want a regular matrix i.e. .Net type[,] use REGULAR_MATRIX_AS_CSHARP_ARRAY instead.
253 %include "std_vector.i"
254 %template(IntVector) std::vector<int>;
255 %template(IntVectorVector) std::vector<std::vector<int> >;
256 VECTOR_AS_CSHARP_ARRAY(int, int, int, IntVector);
257 JAGGED_MATRIX_AS_CSHARP_ARRAY(int, int, int, IntVectorVector);
258 //REGULAR_MATRIX_AS_CSHARP_ARRAY(int, int, int, IntVectorVector);
259 
260 %template(Int64Vector) std::vector<int64_t>;
261 %template(Int64VectorVector) std::vector<std::vector<int64_t> >;
262 VECTOR_AS_CSHARP_ARRAY(int64_t, int64_t, long, Int64Vector);
263 JAGGED_MATRIX_AS_CSHARP_ARRAY(int64_t, int64_t, long, Int64VectorVector);
264 //REGULAR_MATRIX_AS_CSHARP_ARRAY(int64_t, int64_t, long, Int64VectorVector);
265