xlayout.hpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. /***************************************************************************
  2. * Copyright (c) Johan Mabille, Sylvain Corlay and Wolf Vollprecht *
  3. * Copyright (c) QuantStack *
  4. * *
  5. * Distributed under the terms of the BSD 3-Clause License. *
  6. * *
  7. * The full license is in the file LICENSE, distributed with this software. *
  8. ****************************************************************************/
  9. #ifndef XTENSOR_LAYOUT_HPP
  10. #define XTENSOR_LAYOUT_HPP
  11. #include <type_traits>
  12. // Do not include anything else here.
  13. // xlayout.hpp is included in xtensor_forward.hpp
  14. // and we don't want to bring other headers to it.
  15. #include "xtensor_config.hpp"
  16. namespace xt
  17. {
  18. /*! layout_type enum for xcontainer based xexpressions */
  19. enum class layout_type
  20. {
  21. /*! dynamic layout_type: you can resize to row major, column major, or use custom strides */
  22. dynamic = 0x00,
  23. /*! layout_type compatible with all others */
  24. any = 0xFF,
  25. /*! row major layout_type */
  26. row_major = 0x01,
  27. /*! column major layout_type */
  28. column_major = 0x02
  29. };
  30. /**
  31. * Implementation of the following logical table:
  32. *
  33. * | d | a | r | c |
  34. * --+---+---+---+---+
  35. * d | d | d | d | d |
  36. * a | d | a | r | c |
  37. * r | d | r | r | d |
  38. * c | d | c | d | c |
  39. * d = dynamic, a = any, r = row_major, c = column_major.
  40. *
  41. * Using bitmasks to avoid nested if-else statements.
  42. *
  43. * @param args the input layouts.
  44. * @return the output layout, computed with the previous logical table.
  45. */
  46. template <class... Args>
  47. constexpr layout_type compute_layout(Args... args) noexcept;
  48. constexpr layout_type default_assignable_layout(layout_type l) noexcept;
  49. constexpr layout_type layout_remove_any(const layout_type layout) noexcept;
  50. /******************
  51. * Implementation *
  52. ******************/
  53. namespace detail
  54. {
  55. constexpr layout_type compute_layout_impl() noexcept
  56. {
  57. return layout_type::any;
  58. }
  59. constexpr layout_type compute_layout_impl(layout_type l) noexcept
  60. {
  61. return l;
  62. }
  63. constexpr layout_type compute_layout_impl(layout_type lhs, layout_type rhs) noexcept
  64. {
  65. using type = std::underlying_type_t<layout_type>;
  66. return layout_type(static_cast<type>(lhs) & static_cast<type>(rhs));
  67. }
  68. template <class... Args>
  69. constexpr layout_type compute_layout_impl(layout_type lhs, Args... args) noexcept
  70. {
  71. return compute_layout_impl(lhs, compute_layout_impl(args...));
  72. }
  73. }
  74. template <class... Args>
  75. constexpr layout_type compute_layout(Args... args) noexcept
  76. {
  77. return detail::compute_layout_impl(args...);
  78. }
  79. constexpr layout_type default_assignable_layout(layout_type l) noexcept
  80. {
  81. return (l == layout_type::row_major || l == layout_type::column_major) ? l : XTENSOR_DEFAULT_LAYOUT;
  82. }
  83. constexpr layout_type layout_remove_any(const layout_type layout) noexcept
  84. {
  85. return layout == layout_type::any ? XTENSOR_DEFAULT_LAYOUT : layout;
  86. }
  87. }
  88. #endif