/shedskin-0.9/shedskin/lib/builtin/function.hpp

# · C++ Header · 585 lines · 504 code · 63 blank · 18 comment · 90 complexity · 5dacefc8e3711221050200192823a118 MD5 · raw file

  1. /* Copyright 2005-2011 Mark Dufour and contributors; License Expat (See LICENSE) */
  2. /* sum */
  3. template<class A> struct __sumtype1 { typedef A type; };
  4. template<> struct __sumtype1<__ss_bool> { typedef int type; };
  5. template<class A, class B> struct __sumtype2 { typedef A type; };
  6. template<> struct __sumtype2<__ss_bool, __ss_bool> { typedef __ss_int type; };
  7. template<> struct __sumtype2<__ss_bool, __ss_int> { typedef __ss_int type; };
  8. template<> struct __sumtype2<__ss_bool, double> { typedef double type; };
  9. template<> struct __sumtype2<__ss_int, double> { typedef double type; };
  10. template <class U> typename __sumtype1<typename U::for_in_unit>::type __sum(U *iter) {
  11. typename __sumtype1<typename U::for_in_unit>::type result;
  12. result = __zero<typename __sumtype1<typename U::for_in_unit>::type>();
  13. typename U::for_in_unit e;
  14. typename U::for_in_loop __3;
  15. int __2;
  16. U *__1;
  17. bool first = true;
  18. FOR_IN(e,iter,1,2,3)
  19. if(first) {
  20. result = (typename __sumtype1<typename U::for_in_unit>::type)e;
  21. first = false;
  22. }
  23. else
  24. result = __add(result, (typename __sumtype1<typename U::for_in_unit>::type)e);
  25. END_FOR
  26. return result;
  27. }
  28. template <class U, class B> typename __sumtype2<typename U::for_in_unit,B>::type __sum(U *iter, B b) {
  29. typename __sumtype1<typename U::for_in_unit>::type result1 = __sum(iter);
  30. return __add((typename __sumtype2<typename U::for_in_unit,B>::type)b, (typename __sumtype2<typename U::for_in_unit,B>::type)result1);
  31. }
  32. /* max */
  33. template<class A, class B> typename A::for_in_unit ___max(int, B (*key)(typename A::for_in_unit), A *iter) {
  34. typename A::for_in_unit max;
  35. B maxkey, maxkey2;
  36. max = __zero<typename A::for_in_unit>();
  37. maxkey = __zero<B>();
  38. maxkey2 = __zero<B>();;
  39. int first = 1;
  40. typename A::for_in_unit e;
  41. typename A::for_in_loop __3;
  42. int __2;
  43. A *__1;
  44. FOR_IN(e,iter,1,2,3)
  45. if(key) {
  46. maxkey2 = key(e);
  47. if(first || __cmp(maxkey2, maxkey) == 1) {
  48. max = e;
  49. maxkey = maxkey2;
  50. }
  51. } else if(first || __cmp(e, max) == 1)
  52. max = e;
  53. if(first)
  54. first = 0;
  55. END_FOR
  56. if(first)
  57. throw new ValueError(new str("max() arg is an empty sequence"));
  58. return max;
  59. }
  60. /* XXX copy-pasto */
  61. template<class A, class B> typename A::for_in_unit ___max(int, pycall1<B, typename A::for_in_unit> *key, A *iter) {
  62. typename A::for_in_unit max;
  63. B maxkey, maxkey2;
  64. int first = 1;
  65. typename A::for_in_unit e;
  66. typename A::for_in_loop __3;
  67. int __2;
  68. A *__1;
  69. FOR_IN(e,iter,1,2,3)
  70. if(key) {
  71. maxkey2 = key->__call__(e);
  72. if(first || __cmp(maxkey2, maxkey) == 1) {
  73. max = e;
  74. maxkey = maxkey2;
  75. }
  76. } else if(first || __cmp(e, max) == 1)
  77. max = e;
  78. if(first)
  79. first = 0;
  80. END_FOR
  81. if(first)
  82. throw new ValueError(new str("max() arg is an empty sequence"));
  83. return max;
  84. }
  85. template<class A> typename A::for_in_unit ___max(int nn, int, A *iter) { return ___max(nn, (int (*)(typename A::for_in_unit))0, iter); }
  86. template<class T, class B> inline T ___max(int, B (*key)(T), T a, T b) { return (__cmp(key(a), key(b))==1)?a:b; }
  87. template<class T> inline T ___max(int, int, T a, T b) { return (__cmp(a, b)==1)?a:b; }
  88. template<class T, class B> T ___max(int n, B (*key)(T), T a, T b, T c, ...) {
  89. T m = ___max(2, key, ___max(2, key, a, b), c);
  90. B maxkey = key(m);
  91. va_list ap;
  92. va_start(ap, c);
  93. for(int i=0; i<n-3; i++) {
  94. T t = va_arg(ap, T);
  95. if(__cmp(key(t),maxkey)==1)
  96. m=t;
  97. }
  98. va_end(ap);
  99. return m;
  100. }
  101. template<class T> T ___max(int n, int key, T a, T b, T c, ...) {
  102. T m = ___max(2, key, ___max(2, key, a, b), c);
  103. va_list ap;
  104. va_start(ap, c);
  105. for(int i=0; i<n-3; i++) {
  106. T t = va_arg(ap, T);
  107. if(__cmp(t,m)==1) m=t;
  108. }
  109. va_end(ap);
  110. return m;
  111. }
  112. /* min */
  113. template<class A, class B> typename A::for_in_unit ___min(int, B (*key)(typename A::for_in_unit), A *iter) {
  114. typename A::for_in_unit min;
  115. B minkey, minkey2;
  116. min = __zero<typename A::for_in_unit>();
  117. minkey = __zero<B>();
  118. minkey2 = __zero<B>();
  119. int first = 1;
  120. typename A::for_in_unit e;
  121. typename A::for_in_loop __3;
  122. int __2;
  123. A *__1;
  124. FOR_IN(e,iter,1,2,3)
  125. if(key) {
  126. minkey2 = key(e);
  127. if(first || __cmp(minkey2, minkey) == -1) {
  128. min = e;
  129. minkey = minkey2;
  130. }
  131. } else if(first || __cmp(e, min) == -1)
  132. min = e;
  133. if(first)
  134. first = 0;
  135. END_FOR
  136. if(first)
  137. throw new ValueError(new str("min() arg is an empty sequence"));
  138. return min;
  139. }
  140. template<class A> typename A::for_in_unit ___min(int nn, int, A *iter) { return ___min(nn, (int (*)(typename A::for_in_unit))0, iter); }
  141. template<class T, class B> inline T ___min(int, B (*key)(T), T a, T b) { return (__cmp(key(a), key(b))==-1)?a:b; }
  142. template<class T> inline T ___min(int, int, T a, T b) { return (__cmp(a, b)==-1)?a:b; }
  143. template<class T, class B> T ___min(int n, B (*key)(T), T a, T b, T c, ...) {
  144. T m = ___min(2, key, ___min(2, key, a, b), c);
  145. B minkey = key(m);
  146. va_list ap;
  147. va_start(ap, c);
  148. for(int i=0; i<n-3; i++) {
  149. T t = va_arg(ap, T);
  150. if(__cmp(key(t),minkey)==-1)
  151. m=t;
  152. }
  153. va_end(ap);
  154. return m;
  155. }
  156. template<class T> T ___min(int n, int key, T a, T b, T c, ...) { /* XXX */
  157. T m = ___min(2, key, ___min(2, key, a, b), c);
  158. va_list ap;
  159. va_start(ap, c);
  160. for(int i=0; i<n-3; i++) {
  161. T t = va_arg(ap, T);
  162. if(__cmp(t,m)==-1)
  163. m=t;
  164. }
  165. va_end(ap);
  166. return m;
  167. }
  168. /* sorted */
  169. template <class U, class V, class W> list<typename U::for_in_unit> *sorted(U *iter, V cmp, W key, __ss_int reverse) {
  170. typename U::for_in_unit e;
  171. typename U::for_in_loop __3;
  172. int __2;
  173. U *__1;
  174. list<typename U::for_in_unit> *l = new list<typename U::for_in_unit>();
  175. FOR_IN(e,iter,1,2,3)
  176. l->units.push_back(e);
  177. END_FOR
  178. l->sort(cmp, key, reverse);
  179. return l;
  180. }
  181. template <class A, class V, class W> list<A> *sorted(list<A> *x, V cmp, W key, __ss_int reverse) {
  182. list<A> *l = new list<A>();
  183. l->units = x->units;
  184. l->sort(cmp, key, reverse);
  185. return l;
  186. }
  187. template <class A, class V, class W> list<A> *sorted(tuple2<A,A> *x, V cmp, W key, __ss_int reverse) {
  188. list<A> *l = new list<A>();
  189. l->units = x->units;
  190. l->sort(cmp, key, reverse);
  191. return l;
  192. }
  193. template <class V, class W> list<str *> *sorted(str *x, V cmp, W key, __ss_int reverse) {
  194. list<str *> *l = new list<str *>(x);
  195. l->sort(cmp, key, reverse);
  196. return l;
  197. }
  198. /* reversed */
  199. template<class A> class __ss_reverse : public __iter<A> {
  200. public:
  201. pyseq<A> *p;
  202. __ss_int i;
  203. __ss_reverse(pyseq<A> *p) {
  204. this->p = p;
  205. i = len(p);
  206. }
  207. A __get_next() {
  208. if(i>0)
  209. return p->__getitem__(--i); /* XXX avoid wrap, str spec? */
  210. this->__stop_iteration = true;
  211. }
  212. };
  213. template <class A> __ss_reverse<A> *reversed(pyiter<A> *x) {
  214. return new __ss_reverse<A>(new list<A>(x));
  215. }
  216. template <class A> __ss_reverse<A> *reversed(pyseq<A> *x) {
  217. return new __ss_reverse<A>(x);
  218. }
  219. __iter<__ss_int> *reversed(__xrange *x);
  220. /* enumerate */
  221. template<class A> class __enumiter : public __iter<tuple2<__ss_int, A> *> {
  222. public:
  223. __iter<A> *p;
  224. __ss_int i;
  225. __enumiter(pyiter<A> *p) {
  226. this->p = ___iter(p);
  227. i = 0;
  228. }
  229. tuple2<__ss_int, A> *next() {
  230. return new tuple2<__ss_int, A>(2, i++, p->next());
  231. }
  232. };
  233. template <class A> __iter<tuple2<__ss_int, A> *> *enumerate(pyiter<A> *x) {
  234. return new __enumiter<A>(x);
  235. }
  236. /* zip */
  237. list<tuple2<void *, void *> *> *__zip(int nn);
  238. template <class A> list<tuple2<typename A::for_in_unit, typename A::for_in_unit> *> *__zip(int nn, A *iter) {
  239. list<tuple2<typename A::for_in_unit, typename A::for_in_unit> *> *result = (new list<tuple2<typename A::for_in_unit, typename A::for_in_unit> *>());
  240. typename A::for_in_unit e;
  241. typename A::for_in_loop __3;
  242. int __2;
  243. A *__1;
  244. FOR_IN(e,iter,1,2,3)
  245. result->append((new tuple2<typename A::for_in_unit, typename A::for_in_unit>(1, e)));
  246. END_FOR
  247. return result;
  248. }
  249. template <class A, class B> list<tuple2<typename A::for_in_unit, typename B::for_in_unit> *> *__zip(int, A *itera, B *iterb) {
  250. list<tuple2<typename A::for_in_unit, typename B::for_in_unit> *> *result = (new list<tuple2<typename A::for_in_unit, typename B::for_in_unit> *>());
  251. tuple2<typename A::for_in_unit, typename B::for_in_unit> *tuples;
  252. int count = -1;
  253. if(A::is_pyseq && B::is_pyseq) {
  254. count = __SS_MIN(len(itera), len(iterb));
  255. tuples = new tuple2<typename A::for_in_unit, typename B::for_in_unit>[count];
  256. result->units.resize(count);
  257. }
  258. typename A::for_in_unit e;
  259. typename A::for_in_loop __3 = itera->for_in_init();
  260. typename B::for_in_unit f;
  261. typename B::for_in_loop __6 = iterb->for_in_init();
  262. int i = 0;
  263. while(itera->for_in_has_next(__3) and iterb->for_in_has_next(__6)) {
  264. e = itera->for_in_next(__3);
  265. f = iterb->for_in_next(__6);
  266. if(count == -1)
  267. result->append((new tuple2<typename A::for_in_unit, typename B::for_in_unit>(2, e, f)));
  268. else {
  269. tuples[i].__init2__(e, f);
  270. result->units[i] = &tuples[i];
  271. i++;
  272. }
  273. }
  274. return result;
  275. }
  276. template <class A, class B, class C> list<tuple2<typename A::for_in_unit, typename A::for_in_unit> *> *__zip(int, A *itera, B *iterb, C *iterc) {
  277. list<tuple2<typename A::for_in_unit, typename A::for_in_unit> *> *result = (new list<tuple2<typename A::for_in_unit, typename A::for_in_unit> *>());
  278. tuple2<typename A::for_in_unit, typename A::for_in_unit> *tuples;
  279. int count = -1;
  280. if(A::is_pyseq && B::is_pyseq && C::is_pyseq) {
  281. count = __SS_MIN3(len(itera), len(iterb), len(iterc));
  282. tuples = new tuple2<typename A::for_in_unit, typename A::for_in_unit>[count];
  283. result->units.resize(count);
  284. }
  285. typename A::for_in_unit e;
  286. typename A::for_in_loop __3 = itera->for_in_init();
  287. typename B::for_in_unit f;
  288. typename B::for_in_loop __6 = iterb->for_in_init();
  289. typename C::for_in_unit g;
  290. typename C::for_in_loop __7 = iterc->for_in_init();
  291. int i = 0;
  292. while(itera->for_in_has_next(__3) and iterb->for_in_has_next(__6) and iterc->for_in_has_next(__7)) {
  293. e = itera->for_in_next(__3);
  294. f = iterb->for_in_next(__6);
  295. g = iterc->for_in_next(__7);
  296. if(count == -1)
  297. result->append((new tuple2<typename A::for_in_unit, typename A::for_in_unit>(3, e, f, g)));
  298. else {
  299. tuples[i].units.push_back(e);
  300. tuples[i].units.push_back(f);
  301. tuples[i].units.push_back(g);
  302. result->units[i] = &tuples[i];
  303. i++;
  304. }
  305. }
  306. return result;
  307. }
  308. /* next */
  309. template <class A> A next(__iter<A> *iter1, A fillvalue) {
  310. try {
  311. return iter1->next();
  312. } catch(StopIteration *) {
  313. return fillvalue;
  314. }
  315. }
  316. template <class A> A next(__iter<A> *iter1, void *) { return next(iter1, __zero<A>()); }
  317. template <class A> A next(__iter<A> *iter1) { return iter1->next(); }
  318. /* map */
  319. template <class A, class B> list<B> *map(int, B (*func)(typename A::for_in_unit), A *iter) {
  320. if(!func)
  321. throw new ValueError(new str("'map' function argument cannot be None"));
  322. list<B> *result = new list<B>();
  323. int count = -1;
  324. if(A::is_pyseq) {
  325. count = len(iter);
  326. result->units.resize(count);
  327. }
  328. typename A::for_in_unit e;
  329. typename A::for_in_loop __3 = iter->for_in_init();
  330. int i = 0;
  331. while(iter->for_in_has_next(__3)) {
  332. e = iter->for_in_next(__3);
  333. if(count == -1)
  334. result->append((*func)(e));
  335. else
  336. result->units[i++] = (*func)(e);
  337. }
  338. return result;
  339. }
  340. template <class A, class B, class C> list<A> *map(int n, A (*func)(B, C), pyiter<B> *b, pyiter<C> *c) {
  341. if(!func)
  342. throw new ValueError(new str("'map' function argument cannot be None"));
  343. list<A> *result = new list<A>();
  344. __iter<B> *itb = b->__iter__();
  345. __iter<C> *itc = c->__iter__();
  346. B nextb;
  347. C nextc;
  348. int total;
  349. while(1) {
  350. total = 0;
  351. try { nextb = next(itb); total += 1; } catch (StopIteration *) { nextb = __zero<B>(); }
  352. try { nextc = next(itc); total += 1; } catch (StopIteration *) { nextc = __zero<C>(); }
  353. if(total == 0)
  354. break;
  355. result->append((*func)(nextb, nextc));
  356. }
  357. return result;
  358. }
  359. template <class A, class B, class C, class D> list<A> *map(int, A (*func)(B, C, D), pyiter<B> *b1, pyiter<C> *b2, pyiter<D> *b3) {
  360. if(!func)
  361. throw new ValueError(new str("'map' function argument cannot be None"));
  362. list<A> *result = new list<A>();
  363. __iter<B> *itb1 = b1->__iter__();
  364. __iter<C> *itb2 = b2->__iter__();
  365. __iter<D> *itb3 = b3->__iter__();
  366. B nextb1;
  367. C nextb2;
  368. D nextb3;
  369. int total;
  370. while(1) {
  371. total = 0;
  372. try { nextb1 = next(itb1); total += 1; } catch (StopIteration *) { nextb1 = __zero<B>(); }
  373. try { nextb2 = next(itb2); total += 1; } catch (StopIteration *) { nextb2 = __zero<C>(); }
  374. try { nextb3 = next(itb3); total += 1; } catch (StopIteration *) { nextb3 = __zero<D>(); }
  375. if(total == 0)
  376. break;
  377. result->append((*func)(nextb1, nextb2, nextb3));
  378. }
  379. return result;
  380. }
  381. /* reduce */
  382. template<class A, class B, class C> A reduce(A (*func)(A, A), B *iter, C initial) {
  383. A result = initial;
  384. typename B::for_in_loop __7 = iter->for_in_init();
  385. while(iter->for_in_has_next(__7))
  386. result = (*func)(result, iter->for_in_next(__7));
  387. return result;
  388. }
  389. template<class A, class B> A reduce(A (*func)(A, A), B *iter) {
  390. A result;
  391. typename B::for_in_loop __7 = iter->for_in_init();
  392. int first = 1;
  393. while(iter->for_in_has_next(__7)) {
  394. if(first) {
  395. result = iter->for_in_next(__7);
  396. first = 0;
  397. } else
  398. result = (*func)(result, iter->for_in_next(__7));
  399. }
  400. if(first)
  401. throw new TypeError(new str("reduce() of empty sequence with no initial value"));
  402. return result;
  403. }
  404. /* filter */
  405. template <class A, class B> list<typename A::for_in_unit> *filter(B (*func)(typename A::for_in_unit), A *iter) {
  406. list<typename A::for_in_unit> *result = new list<typename A::for_in_unit>();
  407. typename A::for_in_unit e;
  408. typename A::for_in_loop __3 = iter->for_in_init();
  409. while(iter->for_in_has_next(__3)) {
  410. e = iter->for_in_next(__3);
  411. if(func) {
  412. if(___bool((*func)(e)))
  413. result->append(e);
  414. } else if(___bool(e))
  415. result->append(e);
  416. }
  417. return result;
  418. }
  419. template <class A, class B> tuple2<A,A> *filter(B (*func)(A), tuple2<A,A> *a) {
  420. tuple2<A,A> *result = new tuple2<A,A>();
  421. int size = len(a);
  422. A e;
  423. for(int i=0; i<size; i++) {
  424. e = a->units[i];
  425. if(func) {
  426. if(___bool((*func)(e)))
  427. result->units.push_back(e);
  428. } else if(___bool(e))
  429. result->units.push_back(e);
  430. }
  431. return result;
  432. }
  433. template <class B> str *filter(B (*func)(str *), str *a) {
  434. str *result = new str();
  435. int size = len(a);
  436. char e;
  437. str *c;
  438. for(int i=0; i<size; i++) {
  439. e = a->unit[i];
  440. if(func) {
  441. c = __char_cache[((unsigned char)e)];
  442. if(___bool((*func)(c)))
  443. result->unit.push_back(e);
  444. } else
  445. result->unit.push_back(e);
  446. }
  447. return result;
  448. }
  449. template <class A> list<A> *filter(void *func, pyiter<A> *a) { return filter(((int(*)(A))(func)), a); }
  450. inline str *filter(void *, str *a) { return filter(((int(*)(str *))(0)), a); }
  451. template <class A> tuple2<A,A> *filter(void *func, tuple2<A,A> *a) { return filter(((int(*)(A))(func)), a); }
  452. /* any */
  453. template<class A> __ss_bool any(A *iter) {
  454. typename A::for_in_unit e;
  455. typename A::for_in_loop __3;
  456. int __2;
  457. A *__1;
  458. FOR_IN(e,iter,1,2,3)
  459. if(___bool(e))
  460. return True;
  461. END_FOR
  462. return False;
  463. }
  464. /* all */
  465. template<class A> __ss_bool all(A *iter) {
  466. typename A::for_in_unit e;
  467. typename A::for_in_loop __3;
  468. int __2;
  469. A *__1;
  470. FOR_IN(e,iter,1,2,3)
  471. if(!___bool(e))
  472. return False;
  473. END_FOR
  474. return True;
  475. }
  476. /* ord, chr, hex, oct, bin */
  477. static void __throw_ord_exc(size_t s) { /* improve inlining */
  478. throw new TypeError(__modct(new str("ord() expected a character, but string of length %d found"), 1, ___box(s)));
  479. }
  480. inline __ss_int ord(str *s) {
  481. size_t len = s->unit.size();
  482. if(len != 1)
  483. __throw_ord_exc(len);
  484. return (unsigned char)(s->unit[0]);
  485. }
  486. static void __throw_chr_out_of_range() { /* improve inlining */
  487. throw new ValueError(new str("chr() arg not in range(256)"));
  488. }
  489. inline str *chr(int i) {
  490. if(i < 0 || i > 255)
  491. __throw_chr_out_of_range();
  492. return __char_cache[i];
  493. }
  494. inline str *chr(__ss_bool b) { return chr(b.value); }
  495. template<class T> inline str *chr(T t) {
  496. return chr(t->__int__());
  497. }
  498. #ifdef __SS_LONG
  499. inline str *chr(__ss_int i) {
  500. return chr((int)i);
  501. }
  502. template<> inline str *hex(__ss_int i) {
  503. return hex((int)i);
  504. }
  505. template<> inline str *oct(__ss_int i) {
  506. return oct((int)i);
  507. }
  508. template<> inline str *bin(__ss_int i) {
  509. return bin((int)i);
  510. }
  511. #endif
  512. /* id */
  513. template <class T> __ss_int id(T t) {
  514. return (intptr_t)t;
  515. }
  516. template <> __ss_int id(__ss_int);
  517. template <> __ss_int id(double);
  518. template <> __ss_int id(__ss_bool);
  519. /* type */
  520. template<class T> class_ *__type(T t) { return t->__class__; }
  521. template<> class_ *__type(int i);
  522. template<> class_ *__type(double d);