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
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
//!
//! `hicc`提供调用`c++`接口的能力.
//!
//! 三个相关的库:
//! 1. `hicc`核心功能库.
//! 2. `hicc-std`为`c++`标准库中的容器提供`rust api`.
//! 3. `hicc-build`方便编译`c++`适配代码.
//!
//! **约束: 依赖`c++11`或更高版本的特性.**
//!
//! ## 类型映射通用规则
//!
//! 所有数据类型可以分为两大类: `POD`和`class`.
//!
//! |`c++`类型|`rust`参数(`POD`)|`rust`参数(`class`)|`rust`返回值(`POD`)|`rus`返回值(`class`)|说明|
//! |---|---|---|---|---|---|
//! |T|T|T|T|T||
//! |||||`ClassRef<'_, T>`|生命周期和输入关联|
//! |||||`ClassRefMut<'_, T>`|生命周期和输入关联|
//! |||||`ClassPtr<'_, T>`|生命周期和输入关联|
//! |||||`ClassMutPtr<'_, T>`|生命周期和输入关联|
//! |`T&&`|T|T|T|T||
//! |||||`ClassRef<'_, T>`|生命周期和输入关联|
//! |||||`ClassRefMut<'_, T>`|生命周期和输入关联|
//! |||||`ClassPtr<'_, T>`|生命周期和输入关联|
//! |||||`ClassMutPtr<'_, T>`|生命周期和输入关联|
//! |`std::unique_ptr<T>`|`unique_ptr<T>`|T|`unique_ptr<T>`|T||
//! |||||`ClassRef<'_, T>`|生命周期和输入关联|
//! |||||`ClassRefMut<'_, T>`|生命周期和输入关联|
//! |||||`ClassPtr<'_, T>`|生命周期和输入关联|
//! |||||`ClassMutPtr<'_, T>`|生命周期和输入关联|
//! |`std::unique_ptr<T, D>`|`unique_ptr<T>`|`unique_ptr<T>`|`unique_ptr<T>`|`unique_ptr<T>`|`D`非缺省模板参数|
//! |||||`ClassRef<'_, unique_ptr<T>>`|生命周期和输入关联|
//! |||||`ClassRefMut<'_, unique_ptr<T>>`|生命周期和输入关联|
//! |||||`ClassPtr<'_, unique_ptr<T>>`|生命周期和输入关联|
//! |||||`ClassMutPtr<'_, unique_ptr<T>>`|生命周期和输入关联|
//! |`std::shared_ptr<T>`|`shared_ptr<T>`|`shared_ptr<T>`|`shared_ptr<T>`|`shared_ptr<T>`||
//! |||||`ClassRef<'_, shared_ptr<T>>`|生命周期和输入关联|
//! |||||`ClassRefMut<'_, shared_ptr<T>>`|生命周期和输入关联|
//! |||||`ClassPtr<'_, shared_ptr<T>>`|生命周期和输入关联|
//! |||||`ClassMutPtr<'_, shared_ptr<T>>`|生命周期和输入关联|
//! |`const T&`|`&T`|`&T`|`&T`|`ClassRef<'_, T>`||
//! |||||T||
//! |||||`ClassPtr<'_, T>`||
//! |`T&`|`&mut T`|`&mut T`|`&mut T`|`ClassRefMut<'_, T>`||
//! |||||T||
//! |||||`ClassMutPtr<'_, T>`||
//! |`const T*`|`*const T`|`&ClassPtr<'_, T>`|`*const T`|`ClassPtr<'_, T>`|多重指针对应`ClassPtr<'_, T, N>`|
//! |||&T||T|非多重指针|
//! |||&T||ClassRef<'_, T>|非多重指针|
//! |`T*`|`*mut T`|`&ClassMutPtr<'_, T>`|`*mut T`|`ClassMutPtr<'_, T>`|多重指针对应`ClassMutPtr<'_, T, N>`|
//! |||&mut T||T|非多重指针|
//! |||&mut T||ClassRefMut<'_, T>|非多重指针|
//! |`std::function<R(ArgTypes...)>`||Function<fn(ArgTypes...)->R>||Function<fn(ArgTypes...)->R>|其中`R/ArgTypes`遵循上述映射规则|
//! |exception|-|-|`Exception<T>`|`Exception<T>`|其中`T`遵循上述映射规则|
//! |va_list|`...`|-|-|-||
//!
//! 对于`class`类型有几个特点:
//!
//! 1. 无论`c++`返回值类型是什么, `rust`可按需要选择值、引用或指针类型,作为返回值时他们的内存布局完全相同.
//! 1. 输入参数类型需要准确匹配,代表不同的生命周期. 值传递等同于所有权转移,其他为资源借用.
//! 1. `T/ClassRef/ClassRefMut/ClassPtr/ClassMutPtr`总是可以通过`AbiClass::is_null`判断返回是否为空指针.
//! 3. 接口定义时可按`POD`定义为`T/&T/&mut T/*const T/*mut T`, `hicc`完成类型自动转换.参见`import_lib/import_class`.
//!
//! ## 模板(泛型)参数类型映射规则
//!
//! `hicc`支持映射`c++`模板类,要利用`AbiType`来屏蔽上述`POD`和`class`两类模板参数类型上映射规则的差异.
//!
//! 对于模板参数,类型映射规则如下:
//!
//! |c++模板参数类型|`rust`参数|`rust`返回值|
//! |---|---|---|
//! |T|`<T as AbiType>::InputType`|`<T as AbiType>::OutputType`|
//! |const T&|`<T as AbiType>::InputRef<'_>`|`<T as AbiType>::OutputRef<'_>`|
//! |T&|`<T as AbiType>::InputRefMut<'_>`|`<T as AbiType>::OutputRefMut<'_>`|
//! |const T*|`<T as AbiType>::InputPtr<'_>`|`<T as AbiType>::OutputPtr<'_>`|
//! |T*|`<T as AbiType>::InputMutPtr<'_>`|`<T as AbiType>::OutputMutPtr<'_>`|
//!
//! 参考`hicc-std::vector`的`get`接口定义:
//!
//! ```rust!
//! impl<T: AbiType + 'static> vector<T> {
//! pub fn get(&self) -> Option<T::OutputRef<'_>> {
//! //...
//! }
//! }
//! ```
//!
//! **非`class`类型用于`rust`泛型**,必须结合`hicc::Pod<T>`使用.
//!
//! 参考`hicc-std::basic_string<T>`的相关定义:
//!
//! ```rust~
//! type string = basic_string<hicc::Pod<i8>>;
//! type u16string = basic_string<hicc::Pod<i16>>;
//! type u32string = basic_string<hicc::Pod<i32>>;
//! ```
//!
//! ## 二次开发
//!
//! 二次开发分为三个步骤
//!
//! 1. 转换为`cabi`: `c++`代码
//! 2. 映射为`rust api`: `rust`代码
//! 3. `hicc-build`编译`c++`代码
//!
//! ## `hello world`函数和类.
//!
//! 为如下`hello`和`HelloWorld`实现提供`rust api`.
//!
//! ```c++
//! #include <string>
//! std::string hello(const std::string& name) {
//! return std::string("hello ") + name;
//! }
//!
//! class HelloWorld {
//! std::string hello;
//! public:
//! HelloWorld(const std::string& hello): hello(hello) {}
//! std::string hi(const std::string& name) { return hello + " " + name; }
//! };
//! ```
//!
//! ### 转换为`cabi`
//!
//! ```c++
//! // src/cabi.cpp
//! #include <hicc/std/memory.hpp>
//! #include <hicc/std/string.hpp>
//!
//! EXPORT_CLASS_DECLARE(HelloWorld, HelloWorldMethods);
//!
//! // 将成员方法映射为`cabi`接口.
//! struct HelloWorldMethods {
//! EXPORT_MEMBER_METHOD(&HelloWorld::hi);
//! };
//!
//! // 将全局函数和构造函数映射为`cabi`接口.
//! EXPORT_METHODS_BEG(hello_1_0) {
//! EXPORT_METHOD(hello);
//! EXPORT_METHOD(hicc::make_unique<HelloWorld, const std::string&>);
//! }EXPORT_METHODS_END();
//! ```
//!
//! `EXPORT_METHOD`宏完成`c++`接口到`cabi`的映射. 具体参见`import_lib/import_class`.
//!
//! ### 映射为`rust api`
//!
//! ```rust!
//! // 映射HelloWorld
//! hicc::import_class! {
//! class HelloWorld {
//! fn hello(name: &hicc_std::string) -> hicc_std::string;
//! }
//! }
//!
//! // 映射构造函数
//! hicc::import_lib! {
//! #![link_name = "hello_1_0"]
//!
//! fn hello(name: &hicc_std::string) -> hicc_std::string;
//! // 推荐将全局构造函数设置为`crate::HelloWorld`的关联函数.
//! #[member(class = HelloWorld, method = new)]
//! fn helloworld_new(hello: &hicc_std::string) -> HelloWorld;
//! }
//!
//! // 使用
//! fn main() {
//! let hello = hello(&hicc_std::string::from(c"world"));
//! println!("{:?}", hello.as_cstr());
//!
//! let hello = HelloWorld::new(&hicc_std::string::from(c"Hello"));
//! let hi = hello.hi(&hicc_std::string::from(c"World"));
//! println!("{:?}", hi.as_cstr());
//! }
//! ```
//!
//! `import_lib/import_class`中的函数声明将`cabi`接口导入到`rust`. 具体参见`import_lib/import_class`.
//!
//! ### 编译`c++`代码
//!
//! ```rust!
//! // build.rs
//! hicc_build::Build::new().file("src/cabi.cpp").compile("hello_1.0");
//! println!("cargo::rustc-link-lib=hello_1.0");
//! println!("cargo::rustc-link-lib=stdc++");
//! ```
//!
//! `hicc_build`将`c++`代码编译为静态库,将生成的库和`stdc++`链接到`rust`最终生成的二进制件.
//!
//! ## 返回引用类型的处理
//!
//! 如果`HelloWorld`增加如下接口:
//!
//! ```c++
//! class HelloWorld {
//! public:
//! // ...
//! const std::string& get_hello() const { return hello; }
//! };
//! ```
//!
//! `c++`侧适配函数无特殊处理:
//!
//! ```c++
//! EXPORT_METHODS_BEG(hello_1_0) {
//! //...
//! EXPORT_MEMBER_METHOD(&HelloWorld::get_hello);
//! }EXPORT_METHODS_END();
//! ```
//!
//! 根据类型映射规则,`rust api`返回值类型应该是`ClassRef<'_, T>`:
//!
//! ```rust~
//! hicc::import_class! {
//! class HelloWorld {
//! //...
//! fn get_hello(&self) -> hicc::ClassRef<'_, hicc_std::string>;
//! }
//! }
//! ```
//!
//! **推荐利用`import_class`完成类型映射**:
//!
//! ```rust~
//! hicc::import_class! {
//! // 声明为`c++` class
//! class String = hicc_std::string;
//! class HelloWorld {
//! //...
//! // 根据映射规则,`&String`自动转换为`ClassRef<'_, String>`.
//! fn get_hello(&self) -> &String;
//! }
//! }
//! ```
//!
//! **注: `import_lib`有同样的功能**.
//!
//! ```rust~
//! hicc::import_class! {
//! // 重定义类型`hicc_std::string`为`String`
//! class String = hicc_std::string;
//! //...
//! }
//!
//! hicc::import_lib! {
//! // `String`已经被定义,这里只需要声明即可.
//! class String;
//! //...
//! }
//! ```
//!
//! **说明**: 最终生成的代码中, `class`关键字最终都对应到`rust`的`struct`关键字.
//!
///
/// 提供`rust`调用`c++`函数,包括`c++`类构造函数的能力.
///
/// 完整功能由`rust`侧的`import_lib`和`c++`侧的`EXPORT_METHODS_BEG/EXPORT_METHODS_END`配对使用.
///
/// ## `EXPORT_METHODS_BEG/EXPORT_METHODS_END`
///
/// ```c++
/// #include <hicc/hicc.hpp>
///
/// EXPORT_METHODS_BEG(libname) {
/// EXPORT_METHOD(foo);
/// EXPORT_EXCEPT_METHOD(bar);
/// EXPORT_VARIADIC(baz);
/// EXPORT_METHOD((std::function<...>)[](...) {...});
/// }EXPORT_METHODS_END();
/// ```
///
/// 1. 可以有多个`EXPORT_METHODS_BEG/EXPORT_METHODS_END`块
/// 1. `EXPORT_METHODS_BEG(libname)`的宏参数`libname`必须是有效的函数标识.
/// 1. `EXPORT_METHODS_BEG(libname)`的宏参数`libname`需要全局(本库内和多库之间)唯一.
/// 1. `EXPORT_EXCEPT_MEHOD`处理`c++`异常,返回值类型为`hicc::Exceptin<T>`.
/// 1. `EXPORT_VARIADIC`映射包含`...`变长参数的函数. 要求所有参数和返回值不能是`c++`类类型.
/// 1. 对于重载函数和模板函数,`EXPORT_...`时需要指定具体函数类型.
/// 1. 如果希望使用函数的缺省参数,可以利用std::function封装.
///
/// 注: 参见样例`examples/functions`.
///
/// ## `import_lib`
///
/// ```rust!
/// hicc::import_lib! {
/// #![link_name = "libname"]
/// /// 重定义`hicc_std::string`
/// pub class String = hicc_std::string;
/// /// 声明本模块已经定义的类型是`class`
/// class Vector;
/// fn foo();
/// fn bar(vec: &Vector) -> &'static String;
/// }
/// ```
///
/// 1. 库标识一致性: `#![link_name = "..."]`不可省略.其值和`EXPORT_METHODS_BEG`宏参数保持一致,**这是两侧唯一需要名字对齐的地方**.
/// 1. 函数顺序一致: `import_lib`和`EXPORT_METHODS_BEG/EXPORT_METHODS_END`声明的函数按照顺序进行匹配.
/// 1. 函数签名一致: `fn name(Args...) -> R;`对应`EXPORT_METHOD`声明的函数,两侧同序函数的参数和返回值按规则映射.
/// 1. 类型自动映射: 对于声明的`class`类型出现在接口签名上, 会自动完成到`ClassRef/ClassPtr/...`类型的转换.
/// 1. 内存安全增强: 类类型返回值生命周期依赖输入, 可采用非`'static'生命周期的引用或指针.
/// 1. `unsafe`声明: 用户确定是否使用`unsafe`. 如果含变长参数,则会无条件被设置为`unsafe`.
///
/// **注意**:
/// 1. `class`类型自动映射不支持转换函数指针的参数和返回值类型.
/// 2. `import_lib`内部可以包含其他任意有效的`rust item`.
///
/// ## 使用样例
///
/// ```c++
/// int foo(int i, int j = 0);
/// int bar(int i);
/// int bar(int i, int j);
/// template<class T, class ... A>
/// T template_foo(A&& ... args);
/// int baz(int i, va_list);
/// int boo(int i, ...);
/// int doo(std::function<int(int, int)>);
/// void eoo(int i) noexcept(false);
/// ```
///
/// 按照如下方式映射为`cabi`:
///
/// ```c++
/// #include <hicc/hicc.hpp>
///
/// EXPORT_METHODS_BEG(example) {
/// EXPORT_METHOD(foo);
/// EXPORT_METHOD((std::function<int(int)>)[](int v) { return foo(v); });
/// EXPORT_METHOD((int(*)(int))bar);
/// EXPORT_METHOD((int(*)(int, int))bar);
/// EXPORT_METHOD(template_foo<int, int>);
/// EXPORT_METHOD(doo);
/// EXPORT_EXCEPT_METHOD(eoo);
/// EXPORT_METHOD(baz);
/// EXPORT_VARIADIC(boo);
/// }EXPORT_METHODS_END();
/// ```
///
/// ## `rust api`定义和使用
///
/// ```rust!
/// hicc::import_lib! {
/// #![link_name = "example"]
/// fn foo1(v: i32, v2: i32) -> i32;
/// fn foo2(v: i32) -> i32;
/// fn bar1(v: i32) -> i32;
/// fn bar2(v: i32, v3: i32) -> i32;
/// fn template_foo(v1: i32) -> i32;
/// fn doo(v: hicc::Function<fn(i32, i32) -> i32>) -> i32;
/// fn eoo(v: i32) -> hicc::Exception<()>;
/// unsafe fn baz(v1: i32, ...) -> i32;
/// unsafe fn boo(v: i32, ...) -> i32;
/// }
///
/// fn main() {
/// foo1(1, 2);
/// foo2(100);
/// bar1(3);
/// bar2(4, 5);
/// template_foo(6);
/// doo(|v1: i32, v2: i32| -> i32 {
/// println!("rust: {v1} {v2}");
/// v1 + v2 + 100
/// }.into());
/// println!("{:?}", eoo(1));
/// unsafe { baz()(1, 2, 3, 4) };
/// unsafe { boo()(1, 2, 3, 4, 5) };
/// }
/// ```
/// 注: 含可变参数的函数,**映射后的函数实际返回含可变参数的函数指针**.
///
pub use import_lib;
///
/// 实现`c++ class`到`rust struct`的映射.
///
/// `import_class`和 `c++`侧的`EXPORT_CLASS_DECLARE`配套使用.
///
/// ## `EXPORT_CLASS_DECLARE`
///
/// ```c++
/// EXPORT_CLASS_DECLARE(Foo, FooMethods);
///
/// struct FooMethods {
/// EXPORT_MEMBER_METHOD(&Foo::foo);
/// EXPORT_EXCEPT_MEMBER_METHOD(&Foo::bar);
/// EXPORT_DYNAMIC(Foo, Other);
/// EXPORT_DYNAMIC_MOVE(Foo, Other);
/// static void baz(Foo& self) {}
/// EXPORT_METHOD_IN(void, Foo, &FooMethods::baz);
/// };
///
/// ```
///
/// 1. **`EXPORT_CLASS_DECLARE`只能在全局名字空间中使用**.
/// 1. **`EXPORT_CLASS_DECLARE`应在任何含本类类型的函数被映射为`cabi`之前使用**.
/// 1. `EXPORT_DYNAMIC`对应借用场景,而`EXPORT_DYNAMIC_MOVE`对应所有权转移场景.
/// 1. 可以将全局函数映射为成员函数,全局函数的首参数须是本类类型, 且需要`EXPORT_METHOD_IN`.
/// 1. `EXPORT_METHOD_IN`前两个参数必须是类型参数,第一个一般填写`void`, **第二个必须是本类类名**.
/// 1. `EXPORT_METHOD_IN`结合`std::function`可用于对外隐藏缺省参数值.
///
/// ## `EXPORT_CLASS_DELETER`
///
/// `c++`类的析构非`public`时, 需要调用类的特定接口释放对象. 比如下面的设计:
///
/// ```c++
/// class Foo {
/// ~Foo() {}
/// public:
/// static void destroy(Foo* foo) {
/// if (foo) delete foo;
/// }
/// void bar() {}
/// // ...
/// };
/// ```
///
/// 此场景需通过`EXPORT_CLASS_DELETER`告诉`rust`如何释放资源.
///
/// ```text
///
/// EXPORT_CLASS_DECLARE(Foo, FooMethod);
/// EXPORT_CLASS_DELETER(Foo, Foo::destroy);
///
/// struct FooMethod {
/// EXPORT_MEMBER_METHOD(&Foo::bar);
/// };
/// ```
///
/// 同样, **只能在全局名字空间使用`EXPORT_CLASS_DELETER`**.
///
/// ## `import_class`
///
/// ```rust!
/// hicc::import_class! {
/// /// Bar在其他模块定义, 需在这里声明为`class`.
/// class Bar = super::bar::Bar;
///
/// class Foo {
/// fn foo(&self) -> i32;
/// fn bar(&mut self) -> bool;
/// fn as_bar(&self) -> &Bar;
/// fn move_bar(self) -> Bar;
/// fn baz(&self);
/// }
/// }
/// ```
///
/// 1. 按序匹配接口: `class Foo`定义的接口和`FooMethods`中定义接口按顺序匹配.
/// 1. 类型自动映射: 对于声明的`class`类型出现在接口签名上, 会自动完成到`ClassRef/ClassPtr/...`类型的转换.
/// 1. 内存安全增强: 类类型返回值生命周期依赖输入, 可采用非`'static'生命周期的引用或指针.
/// 1. `unsafe`声明: 用户确定是否使用`unsafe`. 如果含变长参数,则会无条件被设置为`unsafe`.
/// 1. `import_class`可以包含其他任意合法的`rust item`.
///
/// ## `c++`模板类映射
///
/// 注: 模板类使用可参考`hicc-std`.
///
/// ### `EXPORT_CLASS_DECLARE`不支持模板类
///
/// 对于模板类,需要显示定义如下特例化代码.
///
/// ```
/// namespace hicc {
/// template<class T> struct MethodsType<Foo<T>> {
/// typedef FooMethods<T> methods_type;
/// };
/// }
/// ```
///
/// ### `EXPORT_METHOD_IN/EXPORT_MEMBER_METHOD_IN`
///
/// 模板类还会有内部类型的映射,比如`std::set<T>::const_iterator`,
/// 这种内部类型的映射必须显示带上外部类的类型信息,这就是`EXPORT_MEMBER_METHOD_IN/EXPORT_METHOD_IN`的应用场景.
///
/// 以如下函数为例说明:
///
/// ```c++
/// #include <hicc/std/map.hpp>
/// struct FooMethods {
/// static void foo(std::map<int, int>& map, std::map<int, int>::const_iterator pos) {}
/// typedef std::map<int, int> Map;
/// EXPORT_METHOD_IN(Map, Foo, &FooMethods::foo);
/// };
/// ```
///
/// 这里`EXPORT_METHOD_IN`的第一个参数必须填写`Map`, 它是映射`std::map<int, int>::const_iteartor`的前提.
///
/// **注意**: 这里不能填写`std::map<int, int>`, 模板参数中的`,`会导致宏错误处理,也不支持`(std::map<int, int>)`.
///
/// 如果一个函数中存在多个模板类的内部类的参数或者返回值,需要利用`std::tuple`来解决.
///
/// ```c++
/// #include <hicc/std/set.hpp>
/// #include <hicc/std/map.hpp>
/// struct FooMethods {
/// static void foo(std::map<int, int>::iterator pos1, std::set<int>::const_iterator pos2) {}
/// typedef std::tuple<std::map<int, int>, std::set<int>> Container;
/// EXPORT_METHOD_IN(Container, Foo, &FooMethods::foo);
/// };
/// ```
///
/// 利用`std::tuple`将多个类组合在一起,保证他们的内部类的映射功能正常使用.
///
/// ### `import_class`
///
/// 在`class`中声明接口的参数,返回值之外使用模板参数,`hicc`无法自动实现类型转换,
/// 需要使用则遵循映射规则选择正确的类型使用.
///
/// 参见`hicc-std`中对`std::set<T>::iterator`的封装:
///
/// ```rust!
/// impl<T: AbiType + 'static> Iterator for set<T> {
/// type Item = T::OutputRef<'_>;
/// fn next(&mut self) -> Option<Self::Item> {
/// //...
/// }
/// }
/// ```
///
/// 1. `rust`侧对应的泛型, 模板参数类型必须支持`hicc::AbiType`, 自动生成的所有类类型都支持.
/// 1. 如果是非类类型,即所有的`POD`类型,需要结合`hicc::Pod<T>`使用单例化具体类型.
///
/// > ```
/// > type VecF64 = hicc_std::vector<hicc::Pod<f64>>;
/// > ```
///
/// ## *继承*机制
///
/// `hicc`支持在`rust`中实现`c++`抽象类的虚函数.
///
/// ### `c++`侧适配
///
/// 如下定义包含虚函数的`c++`类.
///
/// ```c++
/// class Foo {
/// int v;
/// public:
/// Foo(int v): v(v) {}
/// virtual int foo(int) const;
/// void bar(int);
/// virtual ~Foo() {}
/// };
/// ```
///
/// #### `c++`适配
///
/// ```c++
/// #include <hicc/hicc.hpp>
/// #include <hicc/std/memory.hpp>
///
/// EXPORT_CLASS_DECLARE(Foo, FooMethods);
///
/// struct FooMethods {
/// EXPORT_NAMED_MEMBER_METHOD(_foo, &Foo::foo);
/// EXPORT_MEMBER_METHOD(&Foo::bar);
/// };
///
/// class RemoteFoo: public hicc::RemoteProxy<Foo> {
/// public:
/// RemoteFoo(hicc::AbiClass<Foo> remote, int v): hicc::RemoteProxy<Foo>(remote, v) {}
/// virtual int foo(int v) const {
/// CALL_REMOTE(Foo, foo, _foo, v);
/// }
/// };
///
/// EXPORT_METHODS_BEG(class_example) {
/// EXPORT_METHOD(hicc::make_unique_cast<RemoteFoo, Foo, hicc::AbiClass<Foo>, int>);
/// }EXPORT_METHODS_END();
/// ```
///
/// 1. 虚函数须用`EXPORT_NAMED_MEMBER_METHOD`映射,给定一个不和任何成员函数名重复的名字.
/// 1. 映射为`cabi`时, **所有虚函数必须排列在一起并且顺序排列在最前面**.
/// 1. 从`hicc::RemoteProxy<T>`继承实现一个代理类,通过`CALL_REMOTE`完成调用`rust`函数的功能.
/// 1. 代理类构造比`T`构造函数增加参数`hicc::AbiClass<T>`, 它对应`rust`侧的实现.
/// 1. 利用`hicc::make_unique_cast`映射代理类的创建函数.
///
/// ### `rust`侧的适配
///
/// ```text
/// hicc::import_class! {
/// #[virt]
/// class VirtualFoo {
/// fn foo(&self, v: i32) -> i32;
/// }
/// class Foo: VirtualFoo {
/// fn bar(&self, v: i32);
/// }
/// }
///
/// hicc::import_lib! {
/// #![link_name = "class_example"]
///
/// #[virt(class = Foo, name = VirtualFoo, method = from_rust)]
/// fn from_rust(foo: hicc::Interface<Foo>, v: i32) -> Foo;
/// }
///
/// ```
///
/// 1. 虚函数对应接口都在用`#[virt]`修饰的`class`中声明, 它最终被映射为`trait`.
/// 1. `class`可从`#[virt]`修饰的`class`继承, 最多只能继承一个.
/// 1. `rust`侧创建函数对应`c++`侧代理类的构造函数.
/// 1. 推荐利用`#[virt(class = Foo, ...)]`属性将创建函数关联到具体类.
/// 1. 注: `#[virt] class`不支持泛型.
///
/// ## `rust`使用
///
/// ```rust!
/// fn main() {
/// struct MyFoo;
/// // 实现`c++`侧的虚函数.
/// impl VirtualFoo for MyFoo {
/// fn foo(&self, v: i32) -> i32 {
/// println!("rust: {v}");
/// v + 100
/// }
/// }
///
/// let foo = Foo::from_rust(MyFoo, 7);
/// println!("foo = {}", foo.foo(1));
/// foo.bar(100);
/// }
/// ```
///
pub use import_class;
pub use *;
pub use *;
pub use *;
pub use *;
pub use *;
/// 辅助`import_lib`宏的实现.