traits.H 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. // (c) Daniel Llorens - 2013-2016
  2. // This library is free software; you can redistribute it and/or modify it under
  3. // the terms of the GNU Lesser General Public License as published by the Free
  4. // Software Foundation; either version 3 of the License, or (at your option) any
  5. // later version.
  6. /// @file traits.H
  7. /// @brief Array traits: dimension, rank, extent, etc.
  8. #pragma once
  9. #include <cstdint>
  10. #include <vector>
  11. #include <array>
  12. #include <algorithm>
  13. #include "ra/bootstrap.H"
  14. namespace ra {
  15. template <class A> using ra_traits = ra_traits_def<std::decay_t<A>>;
  16. template <class T, class A>
  17. struct ra_traits_def<std::vector<T, A>>
  18. {
  19. using V = std::vector<T, A>;
  20. using value_type = T;
  21. using shape_type = std::array<dim_t, 1>;
  22. constexpr static shape_type shape(V const & v) { return shape_type { { dim_t(v.size()) } }; }
  23. static V make(dim_t const n)
  24. {
  25. return std::vector<T>(n);
  26. }
  27. template <class TT> static V make(dim_t n, TT const & t)
  28. {
  29. return V(n, t);
  30. }
  31. constexpr static dim_t size(V const & v) { return v.size(); }
  32. constexpr static dim_t size_s() { return DIM_ANY; }
  33. constexpr static rank_t rank(V const & v) { return 1; }
  34. constexpr static rank_t rank_s() { return 1; }
  35. };
  36. template <class T, std::size_t N>
  37. struct ra_traits_def<std::array<T, N>>
  38. {
  39. using V = std::array<T, N>;
  40. using value_type = T;
  41. using shape_type = std::array<dim_t, 1>;
  42. constexpr static shape_type shape(V const & v) { return shape_type { { N } }; }
  43. constexpr static V make(dim_t const n)
  44. {
  45. assert(n==N);
  46. return V {};
  47. }
  48. template <class TT> constexpr static V make(dim_t n, TT const & t)
  49. {
  50. assert(n==N);
  51. V r {};
  52. std::fill(r.data(), r.data()+n, t);
  53. return r;
  54. }
  55. constexpr static dim_t size(V const & v) { return v.size(); }
  56. constexpr static dim_t size_s() { return N; }
  57. constexpr static rank_t rank(V const & v) { return 1; }
  58. constexpr static rank_t rank_s() { return 1; };
  59. };
  60. template <class T>
  61. struct ra_traits_def<T *>
  62. {
  63. using V = T *;
  64. using value_type = T;
  65. constexpr static dim_t size(V const & v) { return DIM_BAD; }
  66. constexpr static dim_t size_s() { return DIM_BAD; }
  67. constexpr static rank_t rank(V const & v) { return 1; }
  68. constexpr static rank_t rank_s() { return 1; }
  69. };
  70. template <class T>
  71. struct ra_traits_def<std::initializer_list<T>>
  72. {
  73. using V = std::initializer_list<T>;
  74. using value_type = T;
  75. constexpr static rank_t size(V const & v) { return v.size(); }
  76. constexpr static rank_t rank(V const & v) { return 1; }
  77. constexpr static rank_t rank_s() { return 1; }
  78. constexpr static rank_t size_s() { return DIM_ANY; }
  79. };
  80. // To handle rank-1 arrays of static/dynamic size. TODO: clean up, see temporary.H.
  81. template <class Dim, std::enable_if_t<ra_traits<Dim>::size_s()!=DIM_ANY, int> =0>
  82. void resize(Dim & dim, dim_t k)
  83. {
  84. static_assert(ra_traits<Dim>::rank_s()==1, "bad rank");
  85. assert(k==dim_t(dim.size()));
  86. }
  87. template <class Dim, std::enable_if_t<ra_traits<Dim>::size_s()==DIM_ANY, int> =0>
  88. void resize(Dim & dim, dim_t k)
  89. {
  90. static_assert(ra_traits<Dim>::rank_s()==1 || ra_traits<Dim>::rank_s()==RANK_ANY, "bad rank");
  91. dim.resize(k);
  92. }
  93. } // namespace ra