1 // Copyright (C) 2002 Ronald Garcia
3 // Permission to copy, use, sell and distribute this software is granted
4 // provided this copyright notice appears in all copies.
5 // Permission to modify the code and to distribute modified code is granted
6 // provided this copyright notice appears in all copies, and a notice
7 // that the code was modified is included with the copyright notice.
9 // This software is provided "as is" without express or implied warranty,
10 // and with no claim as to its suitability for any purpose.
13 #ifndef BOOST_STORAGE_ORDER_RG071801_HPP
14 #define BOOST_STORAGE_ORDER_RG071801_HPP
16 #include "boost/multi_array/types.hpp"
17 #include "boost/array.hpp"
18 #include "boost/multi_array/algorithm.hpp"
27 // RG - This is to make things work with VC++. So sad, so sad.
28 class c_storage_order;
29 class fortran_storage_order;
31 template <std::size_t NumDims>
32 class general_storage_order
35 typedef detail::multi_array::size_type size_type;
36 template <typename OrderingIter, typename AscendingIter>
37 general_storage_order(OrderingIter ordering,
38 AscendingIter ascending) {
39 boost::copy_n(ordering,NumDims,ordering_.begin());
40 boost::copy_n(ascending,NumDims,ascending_.begin());
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.
47 general_storage_order(const c_storage_order&) {
48 for (size_type i=0; i != NumDims; ++i) {
49 ordering_[i] = NumDims - 1 - i;
51 ascending_.assign(true);
54 general_storage_order(const fortran_storage_order&) {
55 for (size_type i=0; i != NumDims; ++i) {
58 ascending_.assign(true);
61 size_type ordering(size_type dim) const { return ordering_[dim]; }
62 bool ascending(size_type dim) const { return ascending_[dim]; }
64 bool all_dims_ascending() const {
65 return std::accumulate(ascending_.begin(),ascending_.end(),true,
66 std::logical_and<bool>());
69 bool operator==(general_storage_order const& rhs) const {
70 return (ordering_ == rhs.ordering_) &&
71 (ascending_ == rhs.ascending_);
75 boost::array<size_type,NumDims> ordering_;
76 boost::array<bool,NumDims> ascending_;
81 typedef detail::multi_array::size_type size_type;
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>
87 operator general_storage_order<NumDims>() const {
88 boost::array<size_type,NumDims> ordering;
89 boost::array<bool,NumDims> ascending;
91 for (size_type i=0; i != NumDims; ++i) {
92 ordering[i] = NumDims - 1 - i;
95 return general_storage_order<NumDims>(ordering.begin(),
101 class fortran_storage_order
103 typedef detail::multi_array::size_type size_type;
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>
109 operator general_storage_order<NumDims>() const {
110 boost::array<size_type,NumDims> ordering;
111 boost::array<bool,NumDims> ascending;
113 for (size_type i=0; i != NumDims; ++i) {
117 return general_storage_order<NumDims>(ordering.begin(),
125 #endif // BOOST_ARRAY_STORAGE_RG071801_HPP