source: NonGTP/Boost/boost/multi_array/storage_order.hpp @ 857

Revision 857, 4.0 KB checked in by igarcia, 19 years ago (diff)
Line 
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_STORAGE_ORDER_RG071801_HPP
14#define BOOST_STORAGE_ORDER_RG071801_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
25namespace 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>
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.
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
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
61    size_type ordering(size_type dim) const { return ordering_[dim]; }
62    bool ascending(size_type dim) const { return ascending_[dim]; }
63
64    bool all_dims_ascending() const {
65      return std::accumulate(ascending_.begin(),ascending_.end(),true,
66                      std::logical_and<bool>());
67    }
68
69    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>
87    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>
109    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 // BOOST_ARRAY_STORAGE_RG071801_HPP
Note: See TracBrowser for help on using the repository browser.