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