williamr@2: // Copyright 2002 The Trustees of Indiana University. williamr@2: williamr@2: // Use, modification and distribution is subject to the Boost Software williamr@2: // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at williamr@2: // http://www.boost.org/LICENSE_1_0.txt) williamr@2: williamr@2: // Boost.MultiArray Library williamr@2: // Authors: Ronald Garcia williamr@2: // Jeremy Siek williamr@2: // Andrew Lumsdaine williamr@2: // See http://www.boost.org/libs/multi_array for documentation. williamr@2: williamr@2: #ifndef BOOST_STORAGE_ORDER_RG071801_HPP williamr@2: #define BOOST_STORAGE_ORDER_RG071801_HPP williamr@2: williamr@2: #include "boost/multi_array/types.hpp" williamr@2: #include "boost/array.hpp" williamr@2: #include "boost/multi_array/algorithm.hpp" williamr@2: #include williamr@2: #include williamr@2: #include williamr@2: #include williamr@2: #include williamr@2: williamr@2: namespace boost { williamr@2: williamr@2: // RG - This is to make things work with VC++. So sad, so sad. williamr@2: class c_storage_order; williamr@2: class fortran_storage_order; williamr@2: williamr@2: template williamr@2: class general_storage_order williamr@2: { williamr@2: public: williamr@2: typedef detail::multi_array::size_type size_type; williamr@2: template williamr@2: general_storage_order(OrderingIter ordering, williamr@2: AscendingIter ascending) { williamr@2: boost::detail::multi_array::copy_n(ordering,NumDims,ordering_.begin()); williamr@2: boost::detail::multi_array::copy_n(ascending,NumDims,ascending_.begin()); williamr@2: } williamr@2: williamr@2: // RG - ideally these would not be necessary, but some compilers williamr@2: // don't like template conversion operators. I suspect that not williamr@2: // too many folk will feel the need to use customized williamr@2: // storage_order objects, I sacrifice that feature for compiler support. williamr@2: general_storage_order(const c_storage_order&) { williamr@2: for (size_type i=0; i != NumDims; ++i) { williamr@2: ordering_[i] = NumDims - 1 - i; williamr@2: } williamr@2: ascending_.assign(true); williamr@2: } williamr@2: williamr@2: general_storage_order(const fortran_storage_order&) { williamr@2: for (size_type i=0; i != NumDims; ++i) { williamr@2: ordering_[i] = i; williamr@2: } williamr@2: ascending_.assign(true); williamr@2: } williamr@2: williamr@2: size_type ordering(size_type dim) const { return ordering_[dim]; } williamr@2: bool ascending(size_type dim) const { return ascending_[dim]; } williamr@2: williamr@2: bool all_dims_ascending() const { williamr@2: return std::accumulate(ascending_.begin(),ascending_.end(),true, williamr@2: std::logical_and()); williamr@2: } williamr@2: williamr@2: bool operator==(general_storage_order const& rhs) const { williamr@2: return (ordering_ == rhs.ordering_) && williamr@2: (ascending_ == rhs.ascending_); williamr@2: } williamr@2: williamr@2: protected: williamr@2: boost::array ordering_; williamr@2: boost::array ascending_; williamr@2: }; williamr@2: williamr@2: class c_storage_order williamr@2: { williamr@2: typedef detail::multi_array::size_type size_type; williamr@2: public: williamr@2: // This is the idiom for creating your own custom storage orders. williamr@2: // Not supported by all compilers though! williamr@2: #ifndef __MWERKS__ // Metrowerks screams "ambiguity!" williamr@2: template williamr@2: operator general_storage_order() const { williamr@2: boost::array ordering; williamr@2: boost::array ascending; williamr@2: williamr@2: for (size_type i=0; i != NumDims; ++i) { williamr@2: ordering[i] = NumDims - 1 - i; williamr@2: ascending[i] = true; williamr@2: } williamr@2: return general_storage_order(ordering.begin(), williamr@2: ascending.begin()); williamr@2: } williamr@2: #endif williamr@2: }; williamr@2: williamr@2: class fortran_storage_order williamr@2: { williamr@2: typedef detail::multi_array::size_type size_type; williamr@2: public: williamr@2: // This is the idiom for creating your own custom storage orders. williamr@2: // Not supported by all compilers though! williamr@2: #ifndef __MWERKS__ // Metrowerks screams "ambiguity!" williamr@2: template williamr@2: operator general_storage_order() const { williamr@2: boost::array ordering; williamr@2: boost::array ascending; williamr@2: williamr@2: for (size_type i=0; i != NumDims; ++i) { williamr@2: ordering[i] = i; williamr@2: ascending[i] = true; williamr@2: } williamr@2: return general_storage_order(ordering.begin(), williamr@2: ascending.begin()); williamr@2: } williamr@2: #endif williamr@2: }; williamr@2: williamr@2: } // namespace boost williamr@2: williamr@2: #endif // BOOST_ARRAY_STORAGE_RG071801_HPP