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