concrete.hh 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. // -*- mode: c++; coding: utf-8 -*-
  2. /// @file concrete.hh
  3. /// @brief Obtain concrete type from array expression.
  4. // (c) Daniel Llorens - 2017
  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. #pragma once
  10. #include "ra/big.hh"
  11. namespace ra {
  12. template <class E> struct concrete_type_def_1;
  13. template <class E>
  14. requires (size_s<E>()==DIM_ANY)
  15. struct concrete_type_def_1<E>
  16. {
  17. using type = Big<value_t<E>, E::rank_s()>;
  18. };
  19. template <class E>
  20. requires (size_s<E>()!=DIM_ANY)
  21. struct concrete_type_def_1<E>
  22. {
  23. template <class I> struct T;
  24. template <int ... I> struct T<mp::int_list<I ...>>
  25. {
  26. using type = Small<value_t<E>, E::size_s(I) ...>;
  27. };
  28. using type = typename T<mp::iota<E::rank_s()>>::type;
  29. };
  30. template <class E>
  31. struct concrete_type_def
  32. {
  33. using type = std::conditional_t<
  34. is_scalar<E>,
  35. E, // scalars are their own concrete_type.
  36. typename concrete_type_def_1<std::decay_t<decltype(start(std::declval<E>()))>>::type>;
  37. };
  38. template <class E> using concrete_type = std::decay_t<typename concrete_type_def<E>::type>;
  39. template <class E> inline auto concrete(E && e) { return concrete_type<E>(std::forward<E>(e)); }
  40. template <class E, class X> inline auto
  41. with_same_shape(E && e, X && x)
  42. {
  43. if constexpr (size_s<concrete_type<E>>()!=DIM_ANY) {
  44. return concrete_type<E>(std::forward<X>(x));
  45. } else {
  46. return concrete_type<E>(ra::shape(e), std::forward<X>(x));
  47. }
  48. }
  49. template <class E> inline auto
  50. with_same_shape(E && e)
  51. {
  52. if constexpr (size_s<concrete_type<E>>()!=DIM_ANY) {
  53. return concrete_type<E>();
  54. } else {
  55. return concrete_type<E>(ra::shape(e), ra::none);
  56. }
  57. }
  58. template <class E, class S, class X> inline auto
  59. with_shape(S && s, X && x)
  60. {
  61. if constexpr (size_s<concrete_type<E>>()!=DIM_ANY) {
  62. return concrete_type<E>(std::forward<X>(x));
  63. } else {
  64. return concrete_type<E>(std::forward<S>(s), std::forward<X>(x));
  65. }
  66. }
  67. template <class E, class S, class X> inline auto
  68. with_shape(std::initializer_list<S> && s, X && x)
  69. {
  70. if constexpr (size_s<concrete_type<E>>()!=DIM_ANY) {
  71. return concrete_type<E>(std::forward<X>(x));
  72. } else {
  73. return concrete_type<E>(s, std::forward<X>(x));
  74. }
  75. }
  76. } // namespace ra