]> git.lyx.org Git - lyx.git/blob - boost/boost/multi_array.hpp
leave formula when pressing end at the end of a formula (and similarly
[lyx.git] / boost / boost / multi_array.hpp
1 #ifndef BOOST_MULTI_ARRAY_RG071801_HPP
2 #define BOOST_MULTI_ARRAY_RG071801_HPP
3
4 //
5 // multi_array.hpp - contains the multi_array class template
6 // declaration and definition
7 //
8
9 #include "boost/multi_array/base.hpp"
10 #include "boost/multi_array/collection_concept.hpp"
11 #include "boost/multi_array/copy_array.hpp"
12 #include "boost/multi_array/iterator.hpp"
13 #include "boost/multi_array/subarray.hpp"
14 #include "boost/multi_array/multi_array_ref.hpp"
15 #include "boost/multi_array/algorithm.hpp"
16 #include "boost/array.hpp"
17 #include "boost/type_traits.hpp"
18 #include <algorithm>
19 #include <cstddef>
20 #include <functional>
21 #include <numeric>
22 #include <vector>
23
24 namespace boost {
25
26 template<typename T, std::size_t NumDims,
27   typename Allocator>
28 class multi_array : 
29   public multi_array_ref<T,NumDims>
30 {
31   typedef multi_array_ref<T,NumDims> super_type;
32 public: 
33   typedef typename super_type::value_type value_type;
34   typedef typename super_type::reference reference;
35   typedef typename super_type::const_reference const_reference;
36   typedef typename super_type::iterator iterator;
37   typedef typename super_type::const_iterator const_iterator;
38   typedef typename super_type::iter_base iter_base;
39   typedef typename super_type::const_iter_base const_iter_base;
40   typedef typename super_type::reverse_iterator reverse_iterator;
41   typedef typename super_type::const_reverse_iterator const_reverse_iterator;
42   typedef typename super_type::element element;
43   typedef typename super_type::size_type size_type;
44   typedef typename super_type::difference_type difference_type;
45   typedef typename super_type::index index;
46   typedef typename super_type::extent_range extent_range;
47
48
49   template <std::size_t NDims>
50   struct const_array_view {
51     typedef boost::detail::multi_array::const_multi_array_view<T,NDims> type;
52   };
53
54   template <std::size_t NDims>
55   struct array_view {
56     typedef boost::detail::multi_array::multi_array_view<T,NDims> type;
57   };
58
59   template <class ExtentList>
60   explicit multi_array(ExtentList const& extents) :
61     super_type((T*)initial_base_,extents) {
62     boost::function_requires<
63       detail::multi_array::CollectionConcept<ExtentList> >();
64     allocate_space();
65   }
66
67   template <class ExtentList>
68   explicit multi_array(ExtentList const& extents,
69                        const general_storage_order<NumDims>& so) : 
70     super_type((T*)initial_base_,extents,so) {
71     boost::function_requires<
72       detail::multi_array::CollectionConcept<ExtentList> >();
73     allocate_space();
74   }
75
76   template <class ExtentList>
77   explicit multi_array(ExtentList const& extents,
78                        const general_storage_order<NumDims>& so,
79                        Allocator const& alloc) :
80     super_type((T*)initial_base_,extents,so), allocator_(alloc) {
81     boost::function_requires<
82       detail::multi_array::CollectionConcept<ExtentList> >();
83     allocate_space();
84   }
85
86
87   explicit multi_array(const detail::multi_array
88                        ::extent_gen<NumDims>& ranges) :
89     super_type((T*)initial_base_,ranges) {
90
91     allocate_space();
92   }
93
94
95   explicit multi_array(const detail::multi_array
96                        ::extent_gen<NumDims>& ranges,
97                        const general_storage_order<NumDims>& so) :
98     super_type((T*)initial_base_,ranges,so) {
99
100     allocate_space();
101   }
102
103
104   explicit multi_array(const detail::multi_array
105                        ::extent_gen<NumDims>& ranges,
106                        const general_storage_order<NumDims>& so,
107                        Allocator const& alloc) :
108     super_type((T*)initial_base_,ranges,so), allocator_(alloc) {
109
110     allocate_space();
111   }
112
113   multi_array(const multi_array& rhs) :
114   super_type(rhs), allocator_(rhs.allocator_) {
115     allocate_space();
116     boost::copy_n(rhs.base_,rhs.num_elements(),base_);
117   }
118
119   template <typename OPtr>
120   multi_array(const detail::multi_array::
121               const_sub_array<T,NumDims,OPtr>& rhs) :
122     super_type(rhs) {
123     allocate_space();
124     std::copy(rhs.begin(),rhs.end(),begin());
125   }
126
127   // For some reason, gcc 2.95.2 doesn't pick the above template
128   // member function when passed a subarray, so i was forced to
129   // duplicate the functionality here...
130   multi_array(const detail::multi_array::
131               sub_array<T,NumDims>& rhs) :
132     super_type(rhs) {
133     allocate_space();
134     std::copy(rhs.begin(),rhs.end(),begin());
135   }
136
137   // Since assignment is a deep copy, multi_array_ref 
138   // contains all the necessary code.
139   template <typename ConstMultiArray>
140   multi_array& operator=(const ConstMultiArray& other) {
141     super_type::operator=(other);
142     return *this;
143   }
144
145   multi_array& operator=(const multi_array& other) {
146     if (&other != this) {
147       super_type::operator=(other);
148     }
149     return *this;
150   }
151
152
153   ~multi_array() {
154     deallocate_space();
155   }
156
157 private:
158   void allocate_space() {
159     typename Allocator::const_pointer no_hint=0;
160     base_ = allocator_.allocate(super_type::num_elements(),no_hint);
161     super_type::set_base_ptr(base_);
162     allocated_elements_ = super_type::num_elements();
163     std::uninitialized_fill_n(base_,allocated_elements_,T());
164   }
165
166   void deallocate_space() {
167     if(base_) {
168       for(T* i = base_; i != base_+allocated_elements_; ++i)
169         allocator_.destroy(i);
170       allocator_.deallocate(base_,allocated_elements_);
171     }
172   }    
173   
174   typedef boost::array<size_type,NumDims> size_list;
175   typedef boost::array<index,NumDims> index_list;
176
177   Allocator allocator_;
178   T* base_;
179   size_type allocated_elements_;
180   enum {initial_base_ = 0};
181 };
182
183 } // namespace boost
184
185 #endif // BOOST_MULTI_ARRAY_RG071801_HPP