storage_order.hpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. // Copyright 2002 The Trustees of Indiana University.
  2. // Use, modification and distribution is subject to the Boost Software
  3. // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  4. // http://www.boost.org/LICENSE_1_0.txt)
  5. // Boost.MultiArray Library
  6. // Authors: Ronald Garcia
  7. // Jeremy Siek
  8. // Andrew Lumsdaine
  9. // See http://www.boost.org/libs/multi_array for documentation.
  10. #ifndef BOOST_STORAGE_ORDER_RG071801_HPP
  11. #define BOOST_STORAGE_ORDER_RG071801_HPP
  12. #include "boost/multi_array/types.hpp"
  13. #include "boost/array.hpp"
  14. #include "boost/multi_array/algorithm.hpp"
  15. #include <algorithm>
  16. #include <cstddef>
  17. #include <functional>
  18. #include <numeric>
  19. #include <vector>
  20. namespace boost {
  21. // RG - This is to make things work with VC++. So sad, so sad.
  22. class c_storage_order;
  23. class fortran_storage_order;
  24. template <std::size_t NumDims>
  25. class general_storage_order
  26. {
  27. public:
  28. typedef detail::multi_array::size_type size_type;
  29. template <typename OrderingIter, typename AscendingIter>
  30. general_storage_order(OrderingIter ordering,
  31. AscendingIter ascending) {
  32. boost::detail::multi_array::copy_n(ordering,NumDims,ordering_.begin());
  33. boost::detail::multi_array::copy_n(ascending,NumDims,ascending_.begin());
  34. }
  35. // RG - ideally these would not be necessary, but some compilers
  36. // don't like template conversion operators. I suspect that not
  37. // too many folk will feel the need to use customized
  38. // storage_order objects, I sacrifice that feature for compiler support.
  39. general_storage_order(const c_storage_order&) {
  40. for (size_type i=0; i != NumDims; ++i) {
  41. ordering_[i] = NumDims - 1 - i;
  42. }
  43. ascending_.assign(true);
  44. }
  45. general_storage_order(const fortran_storage_order&) {
  46. for (size_type i=0; i != NumDims; ++i) {
  47. ordering_[i] = i;
  48. }
  49. ascending_.assign(true);
  50. }
  51. size_type ordering(size_type dim) const { return ordering_[dim]; }
  52. bool ascending(size_type dim) const { return ascending_[dim]; }
  53. bool all_dims_ascending() const {
  54. return std::accumulate(ascending_.begin(),ascending_.end(),true,
  55. std::logical_and<bool>());
  56. }
  57. bool operator==(general_storage_order const& rhs) const {
  58. return (ordering_ == rhs.ordering_) &&
  59. (ascending_ == rhs.ascending_);
  60. }
  61. protected:
  62. boost::array<size_type,NumDims> ordering_;
  63. boost::array<bool,NumDims> ascending_;
  64. };
  65. class c_storage_order
  66. {
  67. typedef detail::multi_array::size_type size_type;
  68. public:
  69. // This is the idiom for creating your own custom storage orders.
  70. // Not supported by all compilers though!
  71. #ifndef __MWERKS__ // Metrowerks screams "ambiguity!"
  72. template <std::size_t NumDims>
  73. operator general_storage_order<NumDims>() const {
  74. boost::array<size_type,NumDims> ordering;
  75. boost::array<bool,NumDims> ascending;
  76. for (size_type i=0; i != NumDims; ++i) {
  77. ordering[i] = NumDims - 1 - i;
  78. ascending[i] = true;
  79. }
  80. return general_storage_order<NumDims>(ordering.begin(),
  81. ascending.begin());
  82. }
  83. #endif
  84. };
  85. class fortran_storage_order
  86. {
  87. typedef detail::multi_array::size_type size_type;
  88. public:
  89. // This is the idiom for creating your own custom storage orders.
  90. // Not supported by all compilers though!
  91. #ifndef __MWERKS__ // Metrowerks screams "ambiguity!"
  92. template <std::size_t NumDims>
  93. operator general_storage_order<NumDims>() const {
  94. boost::array<size_type,NumDims> ordering;
  95. boost::array<bool,NumDims> ascending;
  96. for (size_type i=0; i != NumDims; ++i) {
  97. ordering[i] = i;
  98. ascending[i] = true;
  99. }
  100. return general_storage_order<NumDims>(ordering.begin(),
  101. ascending.begin());
  102. }
  103. #endif
  104. };
  105. } // namespace boost
  106. #endif // BOOST_ARRAY_STORAGE_RG071801_HPP