io.cc 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. // -*- mode: c++; coding: utf-8 -*-
  2. // ra-ra/test - IO, formatting.
  3. // (c) Daniel Llorens - 2013-2014
  4. // This library is free software; you can redistribute it and/or modify it under
  5. // the terms of the GNU Lesser General Public License as published by the Free
  6. // Software Foundation; either version 3 of the License, or (at your option) any
  7. // later version.
  8. #include <iostream>
  9. #include <iterator>
  10. #include "ra/test.hh"
  11. #include "ra/complex.hh"
  12. using std::cout, std::endl, std::flush, ra::TestRecorder;
  13. using int3 = ra::Small<int, 3>;
  14. using int2 = ra::Small<int, 2>;
  15. template <class AA, class CC>
  16. void
  17. iocheck(TestRecorder & tr, AA && a, CC && check)
  18. {
  19. std::ostringstream o;
  20. o << a;
  21. cout << "\nwritten: " << o.str() << endl;
  22. std::istringstream i(o.str());
  23. std::decay_t<CC> c;
  24. i >> c;
  25. cout << "\nread: " << c << endl;
  26. tr.test_eq(shape(check), shape(c));
  27. tr.test_eq(check, c);
  28. }
  29. struct Q
  30. {
  31. int x = 1;
  32. };
  33. std::ostream & operator<<(std::ostream & o, Q && q)
  34. {
  35. return (o << q.x);
  36. }
  37. int main()
  38. {
  39. TestRecorder tr;
  40. tr.section("common arrays or slices");
  41. {
  42. ra::Unique<int, 2> a({5, 3}, ra::_0 - ra::_1);
  43. ra::Unique<int, 2> ref({5, 3}, a); // TODO how about an explicit copy() function?
  44. iocheck(tr.info("output of Unique (1)"), a, ref);
  45. iocheck(tr.info("output of Unique (1)"), a, ref);
  46. }
  47. {
  48. ra::Big<int, 1> a = {1};
  49. ra::Big<int, 1> ref = {1};
  50. iocheck(tr.info("Big of rank 1"), a, ref);
  51. }
  52. tr.section("IO format parameters against default (I)");
  53. {
  54. ra::Small<int, 2, 2> A {1, 2, 3, 4};
  55. std::ostringstream o;
  56. o << ra::withshape << format_array(A, "|", "-");
  57. tr.test_eq(std::string("2 2\n1|2-3|4"), o.str());
  58. }
  59. tr.section("IO format parameters against default (II)");
  60. {
  61. ra::Big<int, 2> A({2, 2}, {1, 2, 3, 4});
  62. std::ostringstream o;
  63. o << ra::noshape << format_array(A, "|", "-");
  64. tr.test_eq(std::string("1|2-3|4"), o.str());
  65. }
  66. tr.section("IO manip without FormatArray");
  67. {
  68. ra::Small<int, 2, 2> A {1, 2, 3, 4};
  69. std::ostringstream o;
  70. o << ra::withshape << A;
  71. tr.test_eq(std::string("2 2\n1 2\n3 4"), o.str());
  72. }
  73. tr.section("IO manip without FormatArray");
  74. {
  75. ra::Big<int, 2> A({2, 2}, {1, 2, 3, 4});
  76. std::ostringstream o;
  77. o << ra::noshape << A;
  78. tr.test_eq(std::string("1 2\n3 4"), o.str());
  79. }
  80. tr.section("[ra02a] printing Expr");
  81. {
  82. iocheck(tr.info("output of expr (1)"),
  83. ra::expr([](double i) { return -i; }, start(ra::Small<double, 3>{0, 1, 2})),
  84. ra::Small<double, 3>{0, -1, -2});
  85. iocheck(tr.info("output of expr (2)"),
  86. ra::expr([](double i) { return -i; }, start(ra::Small<double, 3, 2, 3> (ra::_0 - ra::_1 + ra::_2))),
  87. (ra::Small<double, 3, 2, 3> (-(ra::_0 - ra::_1 + ra::_2))));
  88. }
  89. {
  90. ra::Unique<int, 2> a({2, 3}, { 1, 2, 3, 4, 5, 6 });
  91. iocheck(tr.info("output of expr (3)"),
  92. ra::expr([](int i) { return -i; }, a.iter()),
  93. ra::Unique<int, 2>({2, 3}, { -1, -2, -3, -4, -5, -6 }));
  94. }
  95. tr.section("[ra02b] printing array iterators");
  96. {
  97. ra::Unique<int, 2> a({3, 2}, { 1, 2, 3, 4, 5, 6 });
  98. iocheck(tr.info("output of array through its iterator"), a.iter(), a);
  99. // note that transpose({1, 0}, ...) will have dynamic rank, so the type expected from read must also.
  100. iocheck(tr.info("output of transposed array through its iterator"),
  101. transpose({1, 0}, a).iter(),
  102. ra::Unique<int>({2, 3}, { 1, 3, 5, 2, 4, 6 }));
  103. }
  104. tr.section("[ra02c] printing array iterators");
  105. {
  106. ra::Small<int, 3, 2> a { 1, 2, 3, 4, 5, 6 };
  107. iocheck(tr.info("output of array through its iterator"), a.iter(), a);
  108. iocheck(tr.info("output of transposed array through its iterator"),
  109. transpose<1, 0>(a).iter(),
  110. ra::Small<int, 2, 3> { 1, 3, 5, 2, 4, 6 });
  111. }
  112. tr.section("IO can handle undef len iota, too");
  113. {
  114. iocheck(tr.info("output of expr (1)"),
  115. ra::expr([](double i, auto j) { return -i*double(j); }, ra::Small<double, 3>{0, 1, 2}.iter(), ra::iota<0>()),
  116. ra::Small<double, 3>{0, -1, -4});
  117. }
  118. tr.section("IO of var rank expression");
  119. {
  120. ra::Small<int, 2, 2> A {1, 2, 3, 4};
  121. ra::Unique<int> B({2, 2}, {1, 2, 3, 4});
  122. iocheck(tr.info("var rank expr"), A+B, ra::Unique<int>({2, 2}, { 2, 4, 6, 8 }));
  123. }
  124. tr.section("IO of nested type");
  125. {
  126. ra::Small<ra::Big<double, 1>, 3> g = { { 1 }, { 1, 2 }, { 1, 2, 3 } };
  127. iocheck(tr.info("nested type"), g, g);
  128. }
  129. // this behavior depends on [ra13] (std::string is scalar) and the specializations of ostream<< in ply.hh.
  130. tr.section("Non-ra types in format()");
  131. {
  132. std::ostringstream o;
  133. o << ra::format(std::string("once"), " ", std::array {1, 2, 3});
  134. tr.info(o.str()).test_eq(std::string("once 1 2 3"), o.str());
  135. }
  136. // regression against lack of forwarding in ra::format(...)
  137. {
  138. std::ostringstream o;
  139. o << ra::format(Q { 33 });
  140. tr.test_eq(std::string("33"), o.str());
  141. }
  142. // print rank 0
  143. {
  144. ra::Big<int, 0> pick = {}; // uninitialized
  145. cout << format_array(pick) << endl;
  146. cout << ra::noshape << format_array(pick) << endl;
  147. }
  148. return tr.summary();
  149. }