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