return-expr.cc 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. // -*- mode: c++; coding: utf-8 -*-
  2. /// @file return-expr.cc
  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.hh"
  12. #include "ra/test.hh"
  13. #include "ra/ra.hh"
  14. #include <sstream>
  15. using std::cout, std::endl, std::flush, ra::TestRecorder;
  16. using real = double;
  17. template <class A>
  18. inline auto retex_vs(A const & a, real const c)
  19. {
  20. return a-std::move(c); // @NOTE without move(), ra::scalar -> ra::Scalar<real const &>, which is dangling on return.
  21. }
  22. template <class A>
  23. inline auto retex_vsref(A const & a, real const & c)
  24. {
  25. return a-c;
  26. }
  27. int main()
  28. {
  29. TestRecorder tr;
  30. auto test = [&tr](auto t, real const x)
  31. {
  32. using V = decltype(t);
  33. {
  34. V a = {1, 0, 0};
  35. std::ostringstream o;
  36. o << retex_vs(a, x);
  37. cout << "q1. " << o.str() << endl;
  38. V p;
  39. std::istringstream i(o.str());
  40. i >> p;
  41. cout << "q2. " << p << endl;
  42. tr.test_eq(1-x, p[0]);
  43. tr.test_eq(-x, p[1]);
  44. tr.test_eq(-x, p[2]);
  45. V q = retex_vs(a, 2);
  46. cout << "q3. " << q << endl;
  47. tr.test_eq(1-x, p[0]);
  48. tr.test_eq(-x, p[1]);
  49. tr.test_eq(-x, p[2]);
  50. }
  51. using V = decltype(t);
  52. {
  53. V a = {1, 0, 0};
  54. std::ostringstream o;
  55. o << retex_vsref(a, x);
  56. cout << "q1. " << o.str() << endl;
  57. V p;
  58. std::istringstream i(o.str());
  59. i >> p;
  60. cout << "q2. " << p << endl;
  61. tr.test_eq(1-x, p[0]);
  62. tr.test_eq(-x, p[1]);
  63. tr.test_eq(-x, p[2]);
  64. V q = retex_vsref(a, 2);
  65. cout << "q3. " << q << endl;
  66. tr.test_eq(1-x, p[0]);
  67. tr.test_eq(-x, p[1]);
  68. tr.test_eq(-x, p[2]);
  69. }
  70. };
  71. tr.section("vs, small");
  72. {
  73. test(ra::Small<real, 3>(), 2);
  74. test(ra::Small<real, 3>(), 3);
  75. test(ra::Small<real, 3>(), 4);
  76. }
  77. tr.section("vs, large");
  78. {
  79. test(ra::Big<real, 1>(), 2);
  80. test(ra::Big<real, 1>(), 3);
  81. test(ra::Big<real, 1>(), 4);
  82. }
  83. return tr.summary();
  84. }