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