traits.H 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. // -*- mode: c++; coding: utf-8 -*-
  2. /// @file traits.H
  3. /// @brief Array traits: dimension, rank, extent, etc.
  4. // (c) Daniel Llorens - 2013-2016
  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 <cstdint>
  11. #include <vector>
  12. #include <array>
  13. #include <algorithm>
  14. #include "ra/bootstrap.H"
  15. #if defined(RA_CHECK_BOUNDS) && RA_CHECK_BOUNDS==0
  16. #define CHECK_BOUNDS( cond )
  17. #else
  18. #define CHECK_BOUNDS( cond ) RA_ASSERT( cond, 0 )
  19. #endif
  20. namespace ra {
  21. template <class A> using ra_traits = ra_traits_def<std::remove_cv_t<std::remove_reference_t<A>>>;
  22. template <class T, class A>
  23. struct ra_traits_def<std::vector<T, A>>
  24. {
  25. using V = std::vector<T, A>;
  26. using value_type = T;
  27. constexpr static auto shape(V const & v) { return std::array<dim_t, 1> { dim_t(v.size()) }; }
  28. static V make(dim_t const n)
  29. {
  30. return std::vector<T, A>(n);
  31. }
  32. template <class TT> static V make(dim_t n, TT const & t)
  33. {
  34. return V(n, t);
  35. }
  36. constexpr static dim_t size(V const & v) { return v.size(); }
  37. constexpr static dim_t size_s() { return DIM_ANY; }
  38. constexpr static rank_t rank(V const & v) { return 1; }
  39. constexpr static rank_t rank_s() { return 1; }
  40. };
  41. template <class T, std::size_t N>
  42. struct ra_traits_def<std::array<T, N>>
  43. {
  44. using V = std::array<T, N>;
  45. using value_type = T;
  46. constexpr static auto shape(V const & v) { return std::array<dim_t, 1> { N }; }
  47. constexpr static V make(dim_t const n)
  48. {
  49. CHECK_BOUNDS(n==N);
  50. return V {};
  51. }
  52. template <class TT> constexpr static V make(dim_t n, TT const & t)
  53. {
  54. CHECK_BOUNDS(n==N);
  55. V r {};
  56. std::fill(r.data(), r.data()+n, t);
  57. return r;
  58. }
  59. constexpr static dim_t size(V const & v) { return v.size(); }
  60. constexpr static dim_t size_s() { return N; }
  61. constexpr static rank_t rank(V const & v) { return 1; }
  62. constexpr static rank_t rank_s() { return 1; };
  63. };
  64. template <class T>
  65. struct ra_traits_def<T *>
  66. {
  67. using V = T *;
  68. using value_type = T;
  69. constexpr static dim_t size(V const & v) { return DIM_BAD; }
  70. constexpr static dim_t size_s() { return DIM_BAD; }
  71. constexpr static rank_t rank(V const & v) { return 1; }
  72. constexpr static rank_t rank_s() { return 1; }
  73. };
  74. template <class T>
  75. struct ra_traits_def<std::initializer_list<T>>
  76. {
  77. using V = std::initializer_list<T>;
  78. using value_type = T;
  79. constexpr static dim_t size(V const & v) { return v.size(); }
  80. constexpr static rank_t rank(V const & v) { return 1; }
  81. constexpr static rank_t rank_s() { return 1; }
  82. constexpr static dim_t size_s() { return DIM_ANY; }
  83. };
  84. // To handle arrays of static/dynamic size.
  85. template <class A> void
  86. resize(A & a, dim_t k)
  87. {
  88. if constexpr (ra_traits<A>::size_s()==DIM_ANY) {
  89. a.resize(k);
  90. } else {
  91. CHECK_BOUNDS(k==dim_t(a.size_s(0)));
  92. }
  93. }
  94. } // namespace ra
  95. #undef CHECK_BOUNDS