今天闲得无聊,早上起来习惯性瞟一瞟boost,突然看中了它的MPL库,所以自己实现了一个子集消磨时间。
已经实现的功能有:整数运算、闭包、列表处理等。我用了自己的unit test框架,通过写一个函数输出一个属于自己的MPL类型的字符串(譬如List<Int<0>,List<Int<1>,Empty>>产生"[0 , 1]"),然后用自己写的字符串比较,可以发现库里面是否有错。
一下有两份代码,第一份是使用,第二份是自己的MPL的源代码:
首先是unit test的内容:
1 void Test_Type::TestMPL()
2 {
3 VL_UNITTEST_CHECK(ToString<Char<'A'>>::Eval()==L"\'A\'");
4 VL_UNITTEST_CHECK(ToString<WChar<'A'>>::Eval()==L"L\'A\'");
5 VL_UNITTEST_CHECK(ToString<Int<100>>::Eval()==L"100");
6 VL_UNITTEST_CHECK(ToString<Bool<true>>::Eval()==L"true");
7 VL_UNITTEST_CHECK(ToString<Bool<false>>::Eval()==L"false");
8
9 VL_UNITTEST_CHECK((ToString<
10 Plus_<Int<1>,Int<2>>::Type
11 >::Eval()==L"3"));
12 VL_UNITTEST_CHECK((ToString<
13 Empty
14 >::Eval()==L"[]"));
15 VL_UNITTEST_CHECK((ToString<
16 List<Char<'A'>,List<Char<'B'>,List<Char<'C'>,Empty>>>
17 >::Eval()==L"[\'A\' , \'B\' , \'C\']"));
18 VL_UNITTEST_CHECK((ToString<
19 List<Int<0>,List<Int<1>,List<Int<2>,Empty>>>
20 >::Eval()==L"[0 , 1 , 2]"));
21
22 typedef Iterate_<Bind2<Plus,Int<1>>,Int<0>,Int<3>>::Type LIST_012;
23 typedef Iterate_<Bind2<Plus,Int<1>>,Int<3>,Int<3>>::Type LIST_345;
24 typedef Iterate_<Bind2<Plus,Int<1>>,Int<1>,Int<10>>::Type LONG_LIST;
25
26 VL_UNITTEST_CHECK((ToString<
27 Reverse_<LIST_012>::Type
28 >::Eval()==L"[2 , 1 , 0]"));
29
30 VL_UNITTEST_CHECK((ToString<
31 Concat_<LIST_012,LIST_345>::Type
32 >::Eval()==L"[0 , 1 , 2 , 3 , 4 , 5]"));
33
34 VL_UNITTEST_CHECK((ToString<
35 Filter_<Bind2<RevOp<Egt>,Int<2>>,Concat_<LIST_012,LIST_345>>::Type
36 >::Eval()==L"[2 , 3 , 4 , 5]"));
37
38 VL_UNITTEST_CHECK((ToString<
39 Transform_<Bind2<Multiply,Int<2>>,Concat_<LIST_012,LIST_345>>::Type
40 >::Eval()==L"[0 , 2 , 4 , 6 , 8 , 10]"));
41
42 VL_UNITTEST_CHECK((ToString<
43 Transform_<Sqr,Concat_<LIST_012,LIST_345>>::Type
44 >::Eval()==L"[0 , 1 , 4 , 9 , 16 , 25]"));
45
46 VL_UNITTEST_CHECK((ToString<
47 Foldl_<Plus,Int<0>,LONG_LIST>::Type
48 >::Eval()==L"55"));
49
50 VL_UNITTEST_CHECK((ToString<
51 Foldr_<Plus,Int<0>,LONG_LIST>::Type
52 >::Eval()==L"55"));
53
54 VL_UNITTEST_CHECK((ToString<
55 Foldl_<Minus,Int<0>,LONG_LIST>::Type
56 >::Eval()==L"-55"));
57
58 VL_UNITTEST_CHECK((ToString<
59 Foldr_<Minus,Int<0>,LONG_LIST>::Type
60 >::Eval()==L"-5"));
61
62 VL_UNITTEST_CHECK((ToString<
63 Foldl_<Plus,Int<0>,Take_<LONG_LIST,Int<9>>>::Type
64 >::Eval()==L"45"));
65
66 VL_UNITTEST_CHECK((ToString<
67 Foldl_<Plus,Int<0>,Drop_<LONG_LIST,Int<1>>>::Type
68 >::Eval()==L"54"));
69 }
这里是MPL源代码:
1 /*******************************************************************************
2 Vczh Library++ 2.0
3 数据结构::元编程
4 开发者:陈梓瀚
5
6 函数:
7 Plus
8 Minus
9 Multiply
10 Divid
11 Mod
12 Neg
13 Sqr
14 And
15 Or
16 Xor
17 Not
18 Equ
19 Neq
20 Lt
21 Gt
22 Elt
23 Egt
24 If
25 IsEmpty
26 Head
27 Tail
28 Concat
29 Reverse
30 Filter
31 Transform
32 Foldl
33 Foldr
34 Take
35 Drop
36 Count
37 Iterate
38 *******************************************************************************/
39
40 #ifndef VL_MPL
41 #define VL_MPL
42
43 #include "..\Data\VL_Data_String.h"
44
45 namespace vl
46 {
47 namespace mp
48 {
49
50 /*********************************************************************************************************
51 数值
52 *********************************************************************************************************/
53
54 template<char V>
55 struct Char
56 {
57 static const char Value=V;
58 typedef Char<V> Type;
59 };
60
61 template<wchar_t V>
62 struct WChar
63 {
64 static const wchar_t Value=V;
65 typedef WChar<V> Type;
66 };
67
68 template<int V>
69 struct Int
70 {
71 static const int Value=V;
72 typedef Int<V> Type;
73 };
74
75 template<bool V>
76 struct Bool
77 {
78 static const bool Value=V;
79 typedef Bool<V> Type;
80 };
81
82 struct Empty
83 {
84 typedef Empty Type;
85 };
86
87 template<typename H , typename T>
88 struct List
89 {
90 typedef List<H,T> Type;
91 };
92
93 /*********************************************************************************************************
94 函数调用
95 *********************************************************************************************************/
96
97 template<typename F , typename A>
98 struct Apply
99 {
100 typedef typename F::Apply<typename A::Type>::Type Type;
101 };
102
103 template<typename F , typename A , typename B>
104 struct Apply2
105 {
106 typedef typename F::Apply2<typename A::Type,typename B::Type>::Type Type;
107 };
108
109 template<typename F , typename A , typename B , typename C>
110 struct Apply3
111 {
112 typedef typename F::Apply3<typename A::Type,typename B::Type,typename C::Type>::Type Type;
113 };
114
115 template<typename F , typename A , typename B , typename C , typename D>
116 struct Apply4
117 {
118 typedef typename F::Apply4<typename A::Type,typename B::Type,typename C::Type,typename D::Type>::Type Type;
119 };
120
121 template<typename F , typename A , typename B , typename C , typename D , typename E>
122 struct Apply5
123 {
124 typedef typename F::Apply5<typename A::Type,typename B::Type,typename C::Type,typename D::Type,typename E::Type>::Type Type;
125 };
126
127 #define MPL_PACK(NAME) template<typename A> struct NAME##_{typedef typename mp::Apply<NAME,A>::Type Type;}
128 #define MPL_PACK2(NAME) template<typename A , typename B> struct NAME##_{typedef typename mp::Apply2<NAME,A,B>::Type Type;}
129 #define MPL_PACK3(NAME) template<typename A , typename B , typename C> struct NAME##_{typedef typename mp::Apply3<NAME,A,B,C>::Type Type;}
130 #define MPL_PACK4(NAME) template<typename A , typename B , typename C , typename D> struct NAME##_{typedef typename mp::Apply4<NAME,A,B,C,D>::Type Type;}
131 #define MPL_PACK5(NAME) template<typename A , typename B , typename C , typename D , typename E>struct NAME##_{typedef typename mp::Apply5<NAME,A,B,C,D,E>::Type Type;}
132 #define MPL_PRINT_TO_ERROR(NAME) do{typedef NAME Type;typedef NAME::WRONG_TYPE WRONG_TYPE;}while(0)
133
134 /*********************************************************************************************************
135 绑定器
136 *********************************************************************************************************/
137
138 template<typename F , typename P>
139 struct Bind2
140 {
141 template<typename P1>
142 struct Apply
143 {
144 typedef typename mp::Apply2<F,P,P1>::Type Type;
145 };
146
147 typedef Bind2<F,P> Type;
148 };
149
150 template<typename F , typename P>
151 struct Bind3
152 {
153 template<typename P1 , typename P2>
154 struct Apply2
155 {
156 typedef typename mp::Apply3<F,P,P1,P2>::Type Type;
157 };
158
159 typedef Bind3<F,P> Type;
160 };
161
162 template<typename F , typename P>
163 struct Bind4
164 {
165 template<typename P1 , typename P2 , typename P3>
166 struct Apply3
167 {
168 typedef typename mp::Apply4<F,P,P1,P2,P3>::Type Type;
169 };
170
171 typedef Bind4<F,P> Type;
172 };
173
174 template<typename F , typename P>
175 struct Bind5
176 {
177 template<typename P1 , typename P2 , typename P3 , typename P4>
178 struct Apply4
179 {
180 typedef typename mp::Apply5<F,P,P1,P2,P3,P4>::Type Type;
181 };
182
183 typedef Bind5<F,P> Type;
184 };
185
186 template<typename F>
187 struct RevOp
188 {
189 template<typename P1 , typename P2>
190 struct Apply2
191 {
192 typedef typename mp::Apply2<F,P2,P1>::Type Type;
193 };
194
195 typedef RevOp<F> Type;
196 };
197
198 /*********************************************************************************************************
199 基本函数
200 *********************************************************************************************************/
201
202 struct Plus
203 {
204 template<typename A , typename B>
205 struct Apply2
206 {
207 };
208
209 template<int A , int B>
210 struct Apply2<Int<A> , Int<B>>
211 {
212 typedef Int<A+B> Type;
213 };
214
215 typedef Plus Type;
216 };
217 MPL_PACK2(Plus);
218
219 struct Minus
220 {
221 template<typename A , typename B>
222 struct Apply2
223 {
224 };
225
226 template<int A , int B>
227 struct Apply2<Int<A> , Int<B>>
228 {
229 typedef Int<A-B> Type;
230 };
231
232 typedef Minus Type;
233 };
234 MPL_PACK2(Minus);
235
236 struct Multiply
237 {
238 template<typename A , typename B>
239 struct Apply2
240 {
241 };
242
243 template<int A , int B>
244 struct Apply2<Int<A> , Int<B>>
245 {
246 typedef Int<A*B> Type;
247 };
248
249 typedef Multiply Type;
250 };
251 MPL_PACK2(Multiply);
252
253 struct Divid
254 {
255 template<typename A , typename B>
256 struct Apply2
257 {
258 };
259
260 template<int A , int B>
261 struct Apply2<Int<A> , Int<B>>
262 {
263 typedef Int<A/B> Type;
264 };
265
266 typedef Divid Type;
267 };
268 MPL_PACK2(Divid);
269
270 struct Mod
271 {
272 template<typename A , typename B>
273 struct Apply2
274 {
275 };
276
277 template<int A , int B>
278 struct Apply2<Int<A> , Int<B>>
279 {
280 typedef Int<A%B> Type;
281 };
282
283 typedef Mod Type;
284 };
285 MPL_PACK2(Mod);
286
287 struct Neg
288 {
289 template<typename A>
290 struct Apply
291 {
292 };
293
294 template<int A>
295 struct Apply<Int<A>>
296 {
297 typedef Int<-A> Type;
298 };
299
300 typedef Neg Type;
301 };
302 MPL_PACK(Neg);
303
304 struct Sqr
305 {
306 template<typename A>
307 struct Apply
308 {
309 };
310
311 template<int A>
312 struct Apply<Int<A>>
313 {
314 typedef Int<A*A> Type;
315 };
316
317 typedef Sqr Type;
318 };
319 MPL_PACK(Sqr);
320
321 struct And
322 {
323 template<typename A , typename B>
324 struct Apply2
325 {
326 };
327
328 template<bool A , bool B>
329 struct Apply2<Bool<A> , Bool<B>>
330 {
331 typedef Bool<A&&B> Type;
332 };
333
334 typedef And Type;
335 };
336 MPL_PACK2(And);
337
338 struct Or
339 {
340 template<typename A , typename B>
341 struct Apply2
342 {
343 };
344
345 template<bool A , bool B>
346 struct Apply2<Bool<A> , Bool<B>>
347 {
348 typedef Bool<A||B> Type;
349 };
350
351 typedef Or Type;
352 };
353 MPL_PACK2(Or);
354
355 struct Xor
356 {
357 template<typename A , typename B>
358 struct Apply2
359 {
360 };
361
362 template<bool A , bool B>
363 struct Apply2<Bool<A> , Bool<B>>
364 {
365 typedef Bool<A^B> Type;
366 };
367
368 typedef Xor Type;
369 };
370 MPL_PACK2(Xor);
371
372 struct Not
373 {
374 template<typename A>
375 struct Apply
376 {
377 };
378
379 template<bool A>
380 struct Apply<Bool<A>>
381 {
382 typedef Bool<!A> Type;
383 };
384
385 typedef Not Type;
386 };
387 MPL_PACK(Not);
388
389 struct Equ
390 {
391 template<typename A , typename B>
392 struct Apply2
393 {
394 typedef Bool<false> Type;
395 };
396
397 template<typename A>
398 struct Apply2<A , A>
399 {
400 typedef Bool<true> Type;
401 };
402
403 typedef Equ Type;
404 };
405 MPL_PACK2(Equ);
406
407 struct Neq
408 {
409 template<typename A , typename B>
410 struct Apply2
411 {
412 typedef typename Not_<Equ_<A,B>>::Type Type;
413 };
414
415 typedef Neq Type;
416 };
417 MPL_PACK2(Neq);
418
419 struct Lt
420 {
421 template<typename A , typename B>
422 struct Apply2
423 {
424 };
425
426 template<char A , char B>
427 struct Apply2<Char<A> , Char<B>>
428 {
429 typedef Bool<(A<B)> Type;
430 };
431
432 template<wchar_t A , wchar_t B>
433 struct Apply2<WChar<A> , WChar<B>>
434 {
435 typedef Bool<(A<B)> Type;
436 };
437
438 template<int A , int B>
439 struct Apply2<Int<A> , Int<B>>
440 {
441 typedef Bool<(A<B)> Type;
442 };
443
444 typedef Lt Type;
445 };
446 MPL_PACK2(Lt);
447
448 struct Gt
449 {
450 template<typename A , typename B>
451 struct Apply2
452 {
453 typedef typename Not_<Or_<Lt_<A,B>,Equ_<A,B>>>::Type Type;
454 };
455
456 typedef Gt Type;
457 };
458 MPL_PACK2(Gt);
459
460 struct Elt
461 {
462 template<typename A , typename B>
463 struct Apply2
464 {
465 typedef typename Not_<Gt_<A,B>>::Type Type;
466 };
467
468 typedef Elt Type;
469 };
470 MPL_PACK2(Elt);
471
472 struct Egt
473 {
474 template<typename A , typename B>
475 struct Apply2
476 {
477 typedef typename Not_<Lt_<A,B>>::Type Type;
478 };
479
480 typedef Egt Type;
481 };
482 MPL_PACK2(Egt);
483
484 struct If
485 {
486 template<typename A , typename B , typename C>
487 struct Apply3
488 {
489 };
490
491 template<typename A , typename B>
492 struct Apply3<Bool<true> , A , B>
493 {
494 typedef A Type;
495 };
496
497 template<typename A , typename B>
498 struct Apply3<Bool<false> , A , B>
499 {
500 typedef B Type;
501 };
502
503 typedef If Type;
504 };
505 MPL_PACK3(If);
506
507 /*********************************************************************************************************
508 列表操作
509 *********************************************************************************************************/
510
511 struct IsEmpty
512 {
513 template<typename A>
514 struct Apply
515 {
516 };
517
518 template<>
519 struct Apply<Empty>
520 {
521 typedef Bool<true> Type;
522 };
523
524 template<typename H , typename T>
525 struct Apply<List<H,T>>
526 {
527 typedef Bool<false> Type;
528 };
529
530 typedef IsEmpty Type;
531 };
532 MPL_PACK(Empty);
533
534 struct Head
535 {
536 template<typename A>
537 struct Apply
538 {
539 };
540
541 template<typename H , typename T>
542 struct Apply<List<H,T>>
543 {
544 typedef H Type;
545 };
546
547 typedef Head Type;
548 };
549 MPL_PACK(Head);
550
551 struct Tail
552 {
553 template<typename A>
554 struct Apply
555 {
556 };
557
558 template<typename H , typename T>
559 struct Apply<List<H,T>>
560 {
561 typedef T Type;
562 };
563
564 typedef Tail Type;
565 };
566 MPL_PACK(Tail);
567
568 struct Concat
569 {
570 template<typename A , typename B>
571 struct Apply2
572 {
573 };
574
575 template<>
576 struct Apply2<Empty,Empty>
577 {
578 typedef Empty Type;
579 };
580
581 template<typename H2 , typename T2>
582 struct Apply2<Empty,List<H2,T2>>
583 {
584 typedef List<H2,T2> Type;
585 };
586
587 template<typename H1 , typename T1>
588 struct Apply2<List<H1,T1>,Empty>
589 {
590 typedef List<H1,T1> Type;
591 };
592
593 template<typename H1 , typename T1 , typename H2 , typename T2>
594 struct Apply2<List<H1,T1>,List<H2,T2>>
595 {
596 typedef List<H1,typename mp::Apply2<Concat,T1,List<H2,T2>>::Type> Type;
597 };
598
599 typedef Concat Type;
600 };
601 MPL_PACK2(Concat);
602
603 struct Reverse
604 {
605 template<typename A>
606 struct Apply
607 {
608 };
609
610 template<>
611 struct Apply<Empty>
612 {
613 typedef Empty Type;
614 };
615
616 template<typename H>
617 struct Apply<List<H,Empty>>
618 {
619 typedef List<H,Empty> Type;
620 };
621
622 template<typename H , typename T>
623 struct Apply<List<H,T>>
624 {
625 typedef typename Concat_<mp::Apply<Reverse,T>,List<H,Empty>>::Type Type;
626 };
627
628 typedef Reverse Type;
629 };
630 MPL_PACK(Reverse);
631
632 struct Filter
633 {
634 template<typename A , typename B>
635 struct Apply2
636 {
637 };
638
639 template<typename F>
640 struct Apply2<F,Empty>
641 {
642 typedef Empty Type;
643 };
644
645 template<typename F , typename H , typename T>
646 struct Apply2<F,List<H,T>>
647 {
648 typedef
649 typename If_<
650 mp::Apply<F,H>,
651 List<H,typename mp::Apply2<Filter,F,T>::Type>,
652 mp::Apply2<Filter,F,T>
653 >::Type Type;
654 };
655
656 typedef Filter Type;
657 };
658 MPL_PACK2(Filter);
659
660 struct Transform
661 {
662 template<typename A , typename B>
663 struct Apply2
664 {
665 };
666
667 template<typename F>
668 struct Apply2<F,Empty>
669 {
670 typedef Empty Type;
671 };
672
673 template<typename F , typename H , typename T>
674 struct Apply2<F,List<H,T>>
675 {
676 typedef List<typename mp::Apply<F,H>::Type,typename mp::Apply2<Transform,F,T>::Type> Type;
677 };
678
679 typedef Transform Type;
680 };
681 MPL_PACK2(Transform);
682
683 struct Foldl
684 {
685 template<typename A , typename B , typename C>
686 struct Apply3
687 {
688 };
689
690 template<typename F , typename I>
691 struct Apply3<F,I,Empty>
692 {
693 typedef I Type;
694 };
695
696 template<typename F , typename I , typename H , typename T>
697 struct Apply3<F,I,List<H,T>>
698 {
699 typedef typename mp::Apply3<Foldl,F,mp::Apply2<F,I,H>,T>::Type Type;
700 };
701
702 typedef Foldl Type;
703 };
704 MPL_PACK3(Foldl);
705
706 struct Foldr
707 {
708 template<typename A , typename B , typename C>
709 struct Apply3
710 {
711 };
712
713 template<typename F , typename I>
714 struct Apply3<F,I,Empty>
715 {
716 typedef I Type;
717 };
718
719 template<typename F , typename I , typename H , typename T>
720 struct Apply3<F,I,List<H,T>>
721 {
722 typedef typename mp::Apply2<F,H,mp::Apply3<Foldr,F,I,T>>::Type Type;
723 };
724
725 typedef Foldr Type;
726 };
727 MPL_PACK3(Foldr);
728
729 struct Take
730 {
731 template<typename A , typename B>
732 struct Apply2
733 {
734 };
735
736 template<>
737 struct Apply2<Empty,Int<0>>
738 {
739 typedef Empty Type;
740 };
741
742 template<int I>
743 struct Apply2<Empty,Int<I>>
744 {
745 typedef Empty Type;
746 };
747
748 template<typename H , typename T>
749 struct Apply2<List<H,T>,Int<0>>
750 {
751 typedef Empty Type;
752 };
753
754 template<typename H , typename T , int I>
755 struct Apply2<List<H,T>,Int<I>>
756 {
757 typedef List<H,typename mp::Apply2<Take,T,Int<I-1>>::Type> Type;
758 };
759
760 typedef Take Type;
761 };
762 MPL_PACK2(Take);
763
764 struct Drop
765 {
766 template<typename A , typename B>
767 struct Apply2
768 {
769 };
770
771 template<>
772 struct Apply2<Empty,Int<0>>
773 {
774 typedef Empty Type;
775 };
776
777 template<int I>
778 struct Apply2<Empty,Int<I>>
779 {
780 typedef Empty Type;
781 };
782
783 template<typename H , typename T>
784 struct Apply2<List<H,T>,Int<0>>
785 {
786 typedef List<H,T> Type;
787 };
788
789 template<typename H , typename T , int I>
790 struct Apply2<List<H,T>,Int<I>>
791 {
792 typedef typename mp::Apply2<Drop,T,Int<I-1>>::Type Type;
793 };
794
795 typedef Drop Type;
796 };
797 MPL_PACK2(Drop);
798
799 struct Count
800 {
801 template<typename A>
802 struct Apply
803 {
804 };
805
806 template<>
807 struct Apply<Empty>
808 {
809 typedef Int<0> Type;
810 };
811
812 template<typename H , typename T>
813 struct Apply<List<H,T>>
814 {
815 typedef typename Plus_<Int<1>,mp::Apply<Count,T>>::Type Type;
816 };
817
818 typedef Count Type;
819 };
820 MPL_PACK(Count);
821
822 struct Iterate
823 {
824 struct Iterate_Internal
825 {
826 template<typename A , typename B , typename C , typename D>
827 struct Apply4
828 {
829 };
830
831 template<typename F , typename L , typename V>
832 struct Apply4<F,L,V,Int<0>>
833 {
834 typedef L Type;
835 };
836
837 template<typename F , typename L , typename V , int I>
838 struct Apply4<F,L,V,Int<I>>
839 {
840 typedef typename mp::Apply4<Iterate_Internal,F,Concat_<L,List<V,Empty>>,mp::Apply<F,V>,Int<I-1>>::Type Type;
841 };
842 };
843
844 template<typename F , typename V , typename C>
845 struct Apply3
846 {
847 typedef typename mp::Apply4<Iterate_Internal,F,Empty,V,C>::Type Type;
848 };
849
850 typedef Iterate Type;
851 };
852 MPL_PACK3(Iterate);
853
854 /*********************************************************************************************************
855 转字符串
856 *********************************************************************************************************/
857
858 template<typename T>
859 struct ToString
860 {
861 static VUnicodeString Eval()
862 {
863 return L"";
864 }
865 };
866
867 template<bool V>
868 struct ToString<Bool<V>>
869 {
870 static VUnicodeString Eval()
871 {
872 return V?L"true":L"false";
873 }
874 };
875
876 template<char V>
877 struct ToString<Char<V>>
878 {
879 static VUnicodeString Eval()
880 {
881 return L"\'"+VUnicodeString(ToUnicode(V))+L"\'";
882 }
883 };
884
885 template<wchar_t V>
886 struct ToString<WChar<V>>
887 {
888 static VUnicodeString Eval()
889 {
890 return L"L\'"+VUnicodeString(V)+L"\'";
891 }
892 };
893
894 template<int V>
895 struct ToString<Int<V>>
896 {
897 static VUnicodeString Eval()
898 {
899 return V;
900 }
901 };
902
903 template<>
904 struct ToString<Empty>
905 {
906 static VUnicodeString Eval()
907 {
908 return L"[]";
909 }
910 };
911
912 template<typename H>
913 struct ToString<List<H,Empty>>
914 {
915 static VUnicodeString Eval()
916 {
917 return L"["+ToString<H>::Eval()+L"]";
918 }
919 };
920
921 template<typename H , typename T>
922 struct ToString<List<H,T>>
923 {
924 static VUnicodeString Eval()
925 {
926 VUnicodeString Tail=ToString<T>::Eval();
927 Tail.Delete(0,1);
928 return L"["+ToString<H>::Eval()+L" , "+Tail;
929 }
930 };
931 }
932 }
933
934 #endif
posted on 2009-04-08 05:17
陈梓瀚(vczh) 阅读(3705)
评论(13) 编辑 收藏 引用 所属分类:
C++