ra-15.cc 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. // -*- mode: c++; coding: utf-8 -*-
  2. // ra/test - Godbolted version of [ra8] (cf operators.cc)
  3. // (c) Daniel Llorens - 2023
  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. // $CXX -std=c++20 -o tc tc.cc
  9. #include <iostream>
  10. template <class C>
  11. struct Scalar
  12. {
  13. C c;
  14. constexpr C & operator*() { return this->c; }
  15. constexpr C const & operator*() const { return this->c; }
  16. };
  17. template <class C> constexpr auto scalar(C && c) { return Scalar<C> { std::forward<C>(c) }; }
  18. template <class T> requires (std::is_scalar_v<std::decay_t<T>>)
  19. constexpr decltype(auto)
  20. start(T && t) { return scalar(std::forward<T>(t)); }
  21. template <class T>
  22. constexpr decltype(auto)
  23. start(Scalar<T> && t) { return std::forward<decltype(t)>(t); }
  24. template <class A>
  25. constexpr decltype(auto)
  26. FLAT(A && a)
  27. {
  28. return *(start(std::forward<A>(a)));
  29. }
  30. template <class A, class B>
  31. constexpr auto operator +(A && a, B && b)
  32. {
  33. return FLAT(std::forward<A>(a)) + FLAT(std::forward<B>(b));
  34. }
  35. int main()
  36. {
  37. // int x0 = 1 + scalar(2); // not ok for -O1 or higher
  38. // std::cout << x0 << std::endl;
  39. constexpr int q = 1;
  40. constexpr int x1 = q + scalar(2); // ok
  41. std::cout << x1 << std::endl;
  42. // constexpr int x2 = 1 + scalar(2); // not ok
  43. // std::cout << x2 << std::endl;
  44. }