StdDeque.h
Go to the documentation of this file.
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_STDDEQUE_H
27 #define EIGEN_STDDEQUE_H
28 
30 
31 // Define the explicit instantiation (e.g. necessary for the Intel compiler)
32 #if defined(__INTEL_COMPILER) || defined(__GNUC__)
33  #define EIGEN_EXPLICIT_STL_DEQUE_INSTANTIATION(...) template class std::deque<__VA_ARGS__, EIGEN_ALIGNED_ALLOCATOR<__VA_ARGS__> >;
34 #else
35  #define EIGEN_EXPLICIT_STL_DEQUE_INSTANTIATION(...)
36 #endif
37 
43 #define EIGEN_DEFINE_STL_DEQUE_SPECIALIZATION(...) \
44 EIGEN_EXPLICIT_STL_DEQUE_INSTANTIATION(__VA_ARGS__) \
45 namespace std \
46 { \
47  template<typename _Ay> \
48  class deque<__VA_ARGS__, _Ay> \
49  : public deque<__VA_ARGS__, EIGEN_ALIGNED_ALLOCATOR<__VA_ARGS__> > \
50  { \
51  typedef deque<__VA_ARGS__, EIGEN_ALIGNED_ALLOCATOR<__VA_ARGS__> > deque_base; \
52  public: \
53  typedef __VA_ARGS__ value_type; \
54  typedef typename deque_base::allocator_type allocator_type; \
55  typedef typename deque_base::size_type size_type; \
56  typedef typename deque_base::iterator iterator; \
57  explicit deque(const allocator_type& a = allocator_type()) : deque_base(a) {} \
58  template<typename InputIterator> \
59  deque(InputIterator first, InputIterator last, const allocator_type& a = allocator_type()) : deque_base(first, last, a) {} \
60  deque(const deque& c) : deque_base(c) {} \
61  explicit deque(size_type num, const value_type& val = value_type()) : deque_base(num, val) {} \
62  deque(iterator start, iterator end) : deque_base(start, end) {} \
63  deque& operator=(const deque& x) { \
64  deque_base::operator=(x); \
65  return *this; \
66  } \
67  }; \
68 }
69 
70 // check whether we really need the std::deque specialization
71 #if !(defined(_GLIBCXX_DEQUE) && (!EIGEN_GNUC_AT_LEAST(4,1))) /* Note that before gcc-4.1 we already have: std::deque::resize(size_type,const T&). */
72 
73 namespace std {
74 
75 #define EIGEN_STD_DEQUE_SPECIALIZATION_BODY \
76  public: \
77  typedef T value_type; \
78  typedef typename deque_base::allocator_type allocator_type; \
79  typedef typename deque_base::size_type size_type; \
80  typedef typename deque_base::iterator iterator; \
81  typedef typename deque_base::const_iterator const_iterator; \
82  explicit deque(const allocator_type& a = allocator_type()) : deque_base(a) {} \
83  template<typename InputIterator> \
84  deque(InputIterator first, InputIterator last, const allocator_type& a = allocator_type()) \
85  : deque_base(first, last, a) {} \
86  deque(const deque& c) : deque_base(c) {} \
87  explicit deque(size_type num, const value_type& val = value_type()) : deque_base(num, val) {} \
88  deque(iterator start, iterator end) : deque_base(start, end) {} \
89  deque& operator=(const deque& x) { \
90  deque_base::operator=(x); \
91  return *this; \
92  }
93 
94  template<typename T>
96  : public deque<EIGEN_WORKAROUND_MSVC_STL_SUPPORT(T),
97  Eigen::aligned_allocator_indirection<EIGEN_WORKAROUND_MSVC_STL_SUPPORT(T)> >
98 {
102 
103  void resize(size_type new_size)
104  { resize(new_size, T()); }
105 
106 #if defined(_DEQUE_)
107  // workaround MSVC std::deque implementation
108  void resize(size_type new_size, const value_type& x)
109  {
110  if (deque_base::size() < new_size)
111  deque_base::_Insert_n(deque_base::end(), new_size - deque_base::size(), x);
112  else if (new_size < deque_base::size())
113  deque_base::erase(deque_base::begin() + new_size, deque_base::end());
114  }
115  void push_back(const value_type& x)
116  { deque_base::push_back(x); }
117  void push_front(const value_type& x)
118  { deque_base::push_front(x); }
119  using deque_base::insert;
120  iterator insert(const_iterator position, const value_type& x)
121  { return deque_base::insert(position,x); }
122  void insert(const_iterator position, size_type new_size, const value_type& x)
123  { deque_base::insert(position, new_size, x); }
124 #elif defined(_GLIBCXX_DEQUE) && EIGEN_GNUC_AT_LEAST(4,2)
125  // workaround GCC std::deque implementation
126  void resize(size_type new_size, const value_type& x)
127  {
128  if (new_size < deque_base::size())
129  deque_base::_M_erase_at_end(this->_M_impl._M_start + new_size);
130  else
131  deque_base::insert(deque_base::end(), new_size - deque_base::size(), x);
132  }
133 #else
134  // either GCC 4.1 or non-GCC
135  // default implementation which should always work.
136  void resize(size_type new_size, const value_type& x)
137  {
138  if (new_size < deque_base::size())
139  deque_base::erase(deque_base::begin() + new_size, deque_base::end());
140  else if (new_size > deque_base::size())
141  deque_base::insert(deque_base::end(), new_size - deque_base::size(), x);
142  }
143 #endif
144  };
145 }
146 
147 #endif // check whether specialization is actually required
148 
149 #endif // EIGEN_STDDEQUE_H