blob: aaf66330b17dcd17d7599910335591f600dd1b27 [file] [log] [blame]
Narayan Kamathc981c482012-11-02 10:59:05 +00001// 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// This Source Code Form is subject to the terms of the Mozilla
8// Public License v. 2.0. If a copy of the MPL was not distributed
9// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
10
11#ifndef EIGEN_STDDEQUE_H
12#define EIGEN_STDDEQUE_H
13
Carlos Hernandez7faaa9f2014-08-05 17:53:32 -070014#include "details.h"
Narayan Kamathc981c482012-11-02 10:59:05 +000015
16// Define the explicit instantiation (e.g. necessary for the Intel compiler)
17#if defined(__INTEL_COMPILER) || defined(__GNUC__)
18 #define EIGEN_EXPLICIT_STL_DEQUE_INSTANTIATION(...) template class std::deque<__VA_ARGS__, EIGEN_ALIGNED_ALLOCATOR<__VA_ARGS__> >;
19#else
20 #define EIGEN_EXPLICIT_STL_DEQUE_INSTANTIATION(...)
21#endif
22
23/**
24 * This section contains a convenience MACRO which allows an easy specialization of
25 * std::deque such that for data types with alignment issues the correct allocator
26 * is used automatically.
27 */
28#define EIGEN_DEFINE_STL_DEQUE_SPECIALIZATION(...) \
29EIGEN_EXPLICIT_STL_DEQUE_INSTANTIATION(__VA_ARGS__) \
30namespace std \
31{ \
32 template<typename _Ay> \
33 class deque<__VA_ARGS__, _Ay> \
34 : public deque<__VA_ARGS__, EIGEN_ALIGNED_ALLOCATOR<__VA_ARGS__> > \
35 { \
36 typedef deque<__VA_ARGS__, EIGEN_ALIGNED_ALLOCATOR<__VA_ARGS__> > deque_base; \
37 public: \
38 typedef __VA_ARGS__ value_type; \
39 typedef typename deque_base::allocator_type allocator_type; \
40 typedef typename deque_base::size_type size_type; \
41 typedef typename deque_base::iterator iterator; \
42 explicit deque(const allocator_type& a = allocator_type()) : deque_base(a) {} \
43 template<typename InputIterator> \
44 deque(InputIterator first, InputIterator last, const allocator_type& a = allocator_type()) : deque_base(first, last, a) {} \
45 deque(const deque& c) : deque_base(c) {} \
46 explicit deque(size_type num, const value_type& val = value_type()) : deque_base(num, val) {} \
47 deque(iterator start, iterator end) : deque_base(start, end) {} \
48 deque& operator=(const deque& x) { \
49 deque_base::operator=(x); \
50 return *this; \
51 } \
52 }; \
53}
54
55// check whether we really need the std::deque specialization
56#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&). */
57
58namespace std {
59
60#define EIGEN_STD_DEQUE_SPECIALIZATION_BODY \
61 public: \
62 typedef T value_type; \
63 typedef typename deque_base::allocator_type allocator_type; \
64 typedef typename deque_base::size_type size_type; \
65 typedef typename deque_base::iterator iterator; \
66 typedef typename deque_base::const_iterator const_iterator; \
67 explicit deque(const allocator_type& a = allocator_type()) : deque_base(a) {} \
68 template<typename InputIterator> \
69 deque(InputIterator first, InputIterator last, const allocator_type& a = allocator_type()) \
70 : deque_base(first, last, a) {} \
71 deque(const deque& c) : deque_base(c) {} \
72 explicit deque(size_type num, const value_type& val = value_type()) : deque_base(num, val) {} \
73 deque(iterator start, iterator end) : deque_base(start, end) {} \
74 deque& operator=(const deque& x) { \
75 deque_base::operator=(x); \
76 return *this; \
77 }
78
79 template<typename T>
80 class deque<T,EIGEN_ALIGNED_ALLOCATOR<T> >
81 : public deque<EIGEN_WORKAROUND_MSVC_STL_SUPPORT(T),
82 Eigen::aligned_allocator_indirection<EIGEN_WORKAROUND_MSVC_STL_SUPPORT(T)> >
83{
84 typedef deque<EIGEN_WORKAROUND_MSVC_STL_SUPPORT(T),
85 Eigen::aligned_allocator_indirection<EIGEN_WORKAROUND_MSVC_STL_SUPPORT(T)> > deque_base;
86 EIGEN_STD_DEQUE_SPECIALIZATION_BODY
87
88 void resize(size_type new_size)
89 { resize(new_size, T()); }
90
91#if defined(_DEQUE_)
92 // workaround MSVC std::deque implementation
93 void resize(size_type new_size, const value_type& x)
94 {
95 if (deque_base::size() < new_size)
96 deque_base::_Insert_n(deque_base::end(), new_size - deque_base::size(), x);
97 else if (new_size < deque_base::size())
98 deque_base::erase(deque_base::begin() + new_size, deque_base::end());
99 }
100 void push_back(const value_type& x)
101 { deque_base::push_back(x); }
102 void push_front(const value_type& x)
103 { deque_base::push_front(x); }
104 using deque_base::insert;
105 iterator insert(const_iterator position, const value_type& x)
106 { return deque_base::insert(position,x); }
107 void insert(const_iterator position, size_type new_size, const value_type& x)
108 { deque_base::insert(position, new_size, x); }
109#elif defined(_GLIBCXX_DEQUE) && EIGEN_GNUC_AT_LEAST(4,2)
110 // workaround GCC std::deque implementation
111 void resize(size_type new_size, const value_type& x)
112 {
113 if (new_size < deque_base::size())
114 deque_base::_M_erase_at_end(this->_M_impl._M_start + new_size);
115 else
116 deque_base::insert(deque_base::end(), new_size - deque_base::size(), x);
117 }
118#else
119 // either GCC 4.1 or non-GCC
120 // default implementation which should always work.
121 void resize(size_type new_size, const value_type& x)
122 {
123 if (new_size < deque_base::size())
124 deque_base::erase(deque_base::begin() + new_size, deque_base::end());
125 else if (new_size > deque_base::size())
126 deque_base::insert(deque_base::end(), new_size - deque_base::size(), x);
127 }
128#endif
129 };
130}
131
132#endif // check whether specialization is actually required
133
134#endif // EIGEN_STDDEQUE_H