return-expr.C 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. // -*- mode: c++; coding: utf-8 -*-
  2. /// @file return-expr.C
  3. /// @brief Show how careful you have to be when you return an expr object from a function.
  4. // (c) Daniel Llorens - 2014
  5. // This library is free software; you can redistribute it and/or modify it under
  6. // the terms of the GNU Lesser General Public License as published by the Free
  7. // Software Foundation; either version 3 of the License, or (at your option) any
  8. // later version.
  9. // For other examples see fun::project_on_plane or ra::normv. (TODO Those need tests).
  10. #include <iostream>
  11. #include "ra/complex.H"
  12. #include "ra/test.H"
  13. #include "ra/big.H"
  14. #include "ra/operators.H"
  15. #include "ra/io.H"
  16. #include <sstream>
  17. using std::cout, std::endl, std::flush;
  18. using real = double;
  19. template <class A>
  20. inline auto retex_vs(A const & a, real const c)
  21. {
  22. return a-std::move(c); // @NOTE without move(), ra::scalar -> ra::Scalar<real const &>, which is dangling on return.
  23. }
  24. template <class A>
  25. inline auto retex_vsref(A const & a, real const & c)
  26. {
  27. return a-c;
  28. }
  29. int main()
  30. {
  31. TestRecorder tr;
  32. auto test = [&tr](auto t, real const x)
  33. {
  34. using V = decltype(t);
  35. {
  36. V a = {1, 0, 0};
  37. std::ostringstream o;
  38. o << retex_vs(a, x);
  39. cout << "q1. " << o.str() << endl;
  40. V p;
  41. std::istringstream i(o.str());
  42. i >> p;
  43. cout << "q2. " << p << endl;
  44. tr.test_eq(1-x, p[0]);
  45. tr.test_eq(-x, p[1]);
  46. tr.test_eq(-x, p[2]);
  47. V q = retex_vs(a, 2);
  48. cout << "q3. " << q << endl;
  49. tr.test_eq(1-x, p[0]);
  50. tr.test_eq(-x, p[1]);
  51. tr.test_eq(-x, p[2]);
  52. }
  53. using V = decltype(t);
  54. {
  55. V a = {1, 0, 0};
  56. std::ostringstream o;
  57. o << retex_vsref(a, x);
  58. cout << "q1. " << o.str() << endl;
  59. V p;
  60. std::istringstream i(o.str());
  61. i >> p;
  62. cout << "q2. " << p << endl;
  63. tr.test_eq(1-x, p[0]);
  64. tr.test_eq(-x, p[1]);
  65. tr.test_eq(-x, p[2]);
  66. V q = retex_vsref(a, 2);
  67. cout << "q3. " << q << endl;
  68. tr.test_eq(1-x, p[0]);
  69. tr.test_eq(-x, p[1]);
  70. tr.test_eq(-x, p[2]);
  71. }
  72. };
  73. tr.section("vs, small");
  74. {
  75. test(ra::Small<real, 3>(), 2);
  76. test(ra::Small<real, 3>(), 3);
  77. test(ra::Small<real, 3>(), 4);
  78. }
  79. tr.section("vs, large");
  80. {
  81. test(ra::Big<real, 1>(), 2);
  82. test(ra::Big<real, 1>(), 3);
  83. test(ra::Big<real, 1>(), 4);
  84. }
  85. return tr.summary();
  86. }