1/*
2  The %implict macro allows a SwigType (Class) to be accepted
3  as an input parameter and use its implicit constructors when needed.
4
5  For example:
6
7
8  %implicit(A, int, double, B);
9
10  %inline
11  {
12    struct B { };
13    struct A
14    {
15      int ii;
16      A(int i) { ii = 1; }
17      A(double d) { ii = 2; }
18      A(const B& b) { ii = 3; }
19    };
20
21    int get(A a) { return a.ii; }
22  }
23
24  Here, you can call 'get' as
25
26    get(1)    ==> get(A(1))
27    get(2.0)  ==> get(A(2.0))
28    get(B())  ==> get(A(B()))
29
30   and swig will construct an 'A' temporal variable using the
31   corresponding implicit constructor.
32
33
34  The plain implicit macro takes care of simple type list. If it doesn't
35  work because you are passing template types with commas, then use
36  the %implicit_{1,2,3} versions and/or the %arg macro.
37
38*/
39
40%define %implicit_type(Type...)
41%traits_swigtype(Type);
42%enddef
43
44%define %implicit_frag(Type...) ,fragment=SWIG_Traits_frag(Type) %enddef
45
46%define %implicit_code(Type...)
47{
48  Type _v;
49  int res = swig::asval<Type >(obj, &_v);
50  if (SWIG_IsOK(res)) {
51    if (val) *val = new value_type(static_cast<const Type& >(_v));
52    return SWIG_AddNewMask(res);
53  }
54}
55%enddef
56
57/* implicit */
58
59%define %implicit(Type, ...)
60
61%formacro_1(%implicit_type,__VA_ARGS__);
62
63%fragment(SWIG_Traits_frag(Type),"header",
64	  fragment="StdTraits"
65          %formacro_1(%implicit_frag,__VA_ARGS__)) %{
66namespace swig {
67  template <>  struct traits<Type > {
68    typedef pointer_category category;
69    static const char* type_name() { return "Type"; }
70  };
71
72  template <> struct traits_asptr< Type > {
73  typedef Type value_type;
74  static int asptr(SWIG_Object obj, value_type **val) {
75    Type *vptr;
76    static swig_type_info* desc = SWIG_TypeQuery("Type *");
77    int res = SWIG_ConvertPtr(obj, (void **)&vptr, desc, 0);
78    if (SWIG_IsOK(res)) {
79      if (val) *val = vptr;
80      return res;
81    } else {
82      %formacro_1(%implicit_code,__VA_ARGS__)
83    }
84    return SWIG_TypeError;
85  }
86 };
87}
88%}
89
90%typemap_traits_ptr(%checkcode(POINTER),Type);
91%enddef
92
93/* implicit_1 */
94
95
96%define %implicit_1(Type, Imp1)
97%traits_swigtype(Imp1);
98
99%fragment(SWIG_Traits_frag(Type),"header",
100	  fragment="StdTraits",
101	  fragment=SWIG_Traits_frag(Imp1)) %{
102namespace swig {
103  template <>  struct traits< Type > {
104    typedef pointer_category category;
105    static const char* type_name() { return "Type"; }
106  };
107
108  template <> struct traits_asptr< Type > {
109  typedef Type value_type;
110  static int asptr(SWIG_Object obj, value_type **val) {
111    Type *vptr;
112    static swig_type_info* desc = SWIG_TypeQuery("Type *");
113    int res = SWIG_ConvertPtr(obj, (void **)&vptr, desc, 0);
114    if (SWIG_IsOK(res)) {
115      if (val) *val = vptr;
116      return res;
117    } else {
118      %implicit_code(Imp1);
119    }
120    return SWIG_TypeError;
121  }
122 };
123}
124%}
125
126%typemap_traits_ptr(%checkcode(POINTER),Type);
127
128%enddef
129
130/* implicit_2 */
131
132%define %implicit_2(Type, Imp1, Imp2)
133%traits_swigtype(Imp1);
134%traits_swigtype(Imp2);
135
136%fragment(SWIG_Traits_frag(Type),"header",
137	  fragment="StdTraits",
138	  fragment=SWIG_Traits_frag(Imp1),
139	  fragment=SWIG_Traits_frag(Imp2)) %{
140namespace swig {
141  template <>  struct traits< Type > {
142    typedef pointer_category category;
143    static const char* type_name() { return "Type"; }
144  };
145
146  template <> struct traits_asptr< Type > {
147  typedef Type value_type;
148  static int asptr(SWIG_Object obj, value_type **val) {
149    Type *vptr;
150    static swig_type_info* desc = SWIG_TypeQuery("Type *");
151    int res = SWIG_ConvertPtr(obj, (void **)&vptr, desc, 0);
152    if (SWIG_IsOK(res)) {
153      if (val) *val = vptr;
154      return SWIG_OLDOBJ;
155    } else {
156      %implicit_code(Imp1);
157      %implicit_code(Imp2);
158    }
159    return SWIG_TypeError;
160  }
161 };
162}
163%}
164
165%typemap_traits_ptr(%checkcode(POINTER),Type);
166%enddef
167
168
169/* implicit_3 */
170
171%define %implicit_3(Type, Imp1, Imp2, Imp3)
172%traits_swigtype(Imp1);
173%traits_swigtype(Imp2);
174%traits_swigtype(Imp3);
175
176%fragment(SWIG_Traits_frag(Type),"header",
177	  fragment="StdTraits",
178	  fragment=SWIG_Traits_frag(Imp1),
179	  fragment=SWIG_Traits_frag(Imp2),
180	  fragment=SWIG_Traits_frag(Imp3)) %{
181namespace swig {
182  template <>  struct traits< Type > {
183    typedef pointer_category category;
184    static const char* type_name() { return "Type"; }
185  };
186
187  template <> struct traits_asptr< Type > {
188    typedef Type value_type;
189    static int asptr(SWIG_Object obj, value_type **val) {
190    Type *vptr;
191    static swig_type_info* desc = SWIG_TypeQuery("Type *");
192    int res = SWIG_ConvertPtr(obj, (void **)&vptr, desc, 0);
193    if (SWIG_IsOK(res)) {
194      if (val) *val = vptr;
195      return res;
196    } else {
197      %implicit_code(Imp1);
198      %implicit_code(Imp2);
199      %implicit_code(Imp3);
200    }
201    return SWIG_TypeError;
202  }
203 };
204}
205%}
206
207%typemap_traits_ptr(%checkcode(POINTER),Type);
208%enddef
209