Another set of UI messages fixes and tweaks! No functional changes.
[blender.git] / extern / Eigen3 / Eigen / src / StlSupport / StdVector.h
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
5 // Copyright (C) 2009 Hauke Heibel <hauke.heibel@googlemail.com>
6 //
7 // Eigen is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU Lesser General Public
9 // License as published by the Free Software Foundation; either
10 // version 3 of the License, or (at your option) any later version.
11 //
12 // Alternatively, you can redistribute it and/or
13 // modify it under the terms of the GNU General Public License as
14 // published by the Free Software Foundation; either version 2 of
15 // the License, or (at your option) any later version.
16 //
17 // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
20 // GNU General Public License for more details.
21 //
22 // You should have received a copy of the GNU Lesser General Public
23 // License and a copy of the GNU General Public License along with
24 // Eigen. If not, see <http://www.gnu.org/licenses/>.
25
26 #ifndef EIGEN_STDVECTOR_H
27 #define EIGEN_STDVECTOR_H
28
29 #include "Eigen/src/StlSupport/details.h"
30
31 /**
32  * This section contains a convenience MACRO which allows an easy specialization of
33  * std::vector such that for data types with alignment issues the correct allocator
34  * is used automatically.
35  */
36 #define EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(...) \
37 namespace std \
38 { \
39   template<> \
40   class vector<__VA_ARGS__, std::allocator<__VA_ARGS__> >  \
41     : public vector<__VA_ARGS__, EIGEN_ALIGNED_ALLOCATOR<__VA_ARGS__> > \
42   { \
43     typedef vector<__VA_ARGS__, EIGEN_ALIGNED_ALLOCATOR<__VA_ARGS__> > vector_base; \
44   public: \
45     typedef __VA_ARGS__ value_type; \
46     typedef vector_base::allocator_type allocator_type; \
47     typedef vector_base::size_type size_type;  \
48     typedef vector_base::iterator iterator;  \
49     explicit vector(const allocator_type& a = allocator_type()) : vector_base(a) {}  \
50     template<typename InputIterator> \
51     vector(InputIterator first, InputIterator last, const allocator_type& a = allocator_type()) : vector_base(first, last, a) {} \
52     vector(const vector& c) : vector_base(c) {}  \
53     explicit vector(size_type num, const value_type& val = value_type()) : vector_base(num, val) {} \
54     vector(iterator start, iterator end) : vector_base(start, end) {}  \
55     vector& operator=(const vector& x) {  \
56       vector_base::operator=(x);  \
57       return *this;  \
58     } \
59   }; \
60 }
61
62 namespace std {
63
64 #define EIGEN_STD_VECTOR_SPECIALIZATION_BODY \
65   public:  \
66     typedef T value_type; \
67     typedef typename vector_base::allocator_type allocator_type; \
68     typedef typename vector_base::size_type size_type;  \
69     typedef typename vector_base::iterator iterator;  \
70     typedef typename vector_base::const_iterator const_iterator;  \
71     explicit vector(const allocator_type& a = allocator_type()) : vector_base(a) {}  \
72     template<typename InputIterator> \
73     vector(InputIterator first, InputIterator last, const allocator_type& a = allocator_type()) \
74     : vector_base(first, last, a) {} \
75     vector(const vector& c) : vector_base(c) {}  \
76     explicit vector(size_type num, const value_type& val = value_type()) : vector_base(num, val) {} \
77     vector(iterator start, iterator end) : vector_base(start, end) {}  \
78     vector& operator=(const vector& x) {  \
79       vector_base::operator=(x);  \
80       return *this;  \
81     }
82
83   template<typename T>
84   class vector<T,EIGEN_ALIGNED_ALLOCATOR<T> >
85     : public vector<EIGEN_WORKAROUND_MSVC_STL_SUPPORT(T),
86                     Eigen::aligned_allocator_indirection<EIGEN_WORKAROUND_MSVC_STL_SUPPORT(T)> >
87 {
88   typedef vector<EIGEN_WORKAROUND_MSVC_STL_SUPPORT(T),
89                  Eigen::aligned_allocator_indirection<EIGEN_WORKAROUND_MSVC_STL_SUPPORT(T)> > vector_base;
90   EIGEN_STD_VECTOR_SPECIALIZATION_BODY
91
92   void resize(size_type new_size)
93   { resize(new_size, T()); }
94
95 #if defined(_VECTOR_)
96   // workaround MSVC std::vector implementation
97   void resize(size_type new_size, const value_type& x)
98   {
99     if (vector_base::size() < new_size)
100       vector_base::_Insert_n(vector_base::end(), new_size - vector_base::size(), x);
101     else if (new_size < vector_base::size())
102       vector_base::erase(vector_base::begin() + new_size, vector_base::end());
103   }
104   void push_back(const value_type& x)
105   { vector_base::push_back(x); } 
106   using vector_base::insert;  
107   iterator insert(const_iterator position, const value_type& x)
108   { return vector_base::insert(position,x); }
109   void insert(const_iterator position, size_type new_size, const value_type& x)
110   { vector_base::insert(position, new_size, x); }
111 #elif defined(_GLIBCXX_VECTOR) && (!(EIGEN_GNUC_AT_LEAST(4,1)))
112   /* Note that before gcc-4.1 we already have: std::vector::resize(size_type,const T&).
113    * However, this specialization is still needed to make the above EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION trick to work. */
114   void resize(size_type new_size, const value_type& x)
115   {
116     vector_base::resize(new_size,x);
117   }
118 #elif defined(_GLIBCXX_VECTOR) && EIGEN_GNUC_AT_LEAST(4,2)
119   // workaround GCC std::vector implementation
120   void resize(size_type new_size, const value_type& x)
121   {
122     if (new_size < vector_base::size())
123       vector_base::_M_erase_at_end(this->_M_impl._M_start + new_size);
124     else
125       vector_base::insert(vector_base::end(), new_size - vector_base::size(), x);
126   }
127 #else
128   // either GCC 4.1 or non-GCC
129   // default implementation which should always work.
130   void resize(size_type new_size, const value_type& x)
131   {
132     if (new_size < vector_base::size())
133       vector_base::erase(vector_base::begin() + new_size, vector_base::end());
134     else if (new_size > vector_base::size())
135       vector_base::insert(vector_base::end(), new_size - vector_base::size(), x);
136   }
137 #endif
138   };
139 }
140
141 #endif // EIGEN_STDVECTOR_H