xref: /aosp_15_r20/external/eigen/Eigen/src/StlSupport/StdDeque.h (revision bf2c37156dfe67e5dfebd6d394bad8b2ab5804d4)
1*bf2c3715SXin Li // This file is part of Eigen, a lightweight C++ template library
2*bf2c3715SXin Li // for linear algebra.
3*bf2c3715SXin Li //
4*bf2c3715SXin Li // Copyright (C) 2009 Gael Guennebaud <[email protected]>
5*bf2c3715SXin Li // Copyright (C) 2009 Hauke Heibel <[email protected]>
6*bf2c3715SXin Li //
7*bf2c3715SXin Li // This Source Code Form is subject to the terms of the Mozilla
8*bf2c3715SXin Li // Public License v. 2.0. If a copy of the MPL was not distributed
9*bf2c3715SXin Li // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
10*bf2c3715SXin Li 
11*bf2c3715SXin Li #ifndef EIGEN_STDDEQUE_H
12*bf2c3715SXin Li #define EIGEN_STDDEQUE_H
13*bf2c3715SXin Li 
14*bf2c3715SXin Li #include "details.h"
15*bf2c3715SXin Li 
16*bf2c3715SXin Li /**
17*bf2c3715SXin Li  * This section contains a convenience MACRO which allows an easy specialization of
18*bf2c3715SXin Li  * std::deque such that for data types with alignment issues the correct allocator
19*bf2c3715SXin Li  * is used automatically.
20*bf2c3715SXin Li  */
21*bf2c3715SXin Li #define EIGEN_DEFINE_STL_DEQUE_SPECIALIZATION(...) \
22*bf2c3715SXin Li namespace std \
23*bf2c3715SXin Li { \
24*bf2c3715SXin Li   template<> \
25*bf2c3715SXin Li   class deque<__VA_ARGS__, std::allocator<__VA_ARGS__> >           \
26*bf2c3715SXin Li     : public deque<__VA_ARGS__, EIGEN_ALIGNED_ALLOCATOR<__VA_ARGS__> > \
27*bf2c3715SXin Li   { \
28*bf2c3715SXin Li     typedef deque<__VA_ARGS__, EIGEN_ALIGNED_ALLOCATOR<__VA_ARGS__> > deque_base; \
29*bf2c3715SXin Li   public: \
30*bf2c3715SXin Li     typedef __VA_ARGS__ value_type; \
31*bf2c3715SXin Li     typedef deque_base::allocator_type allocator_type; \
32*bf2c3715SXin Li     typedef deque_base::size_type size_type;  \
33*bf2c3715SXin Li     typedef deque_base::iterator iterator;  \
34*bf2c3715SXin Li     explicit deque(const allocator_type& a = allocator_type()) : deque_base(a) {}  \
35*bf2c3715SXin Li     template<typename InputIterator> \
36*bf2c3715SXin Li     deque(InputIterator first, InputIterator last, const allocator_type& a = allocator_type()) : deque_base(first, last, a) {} \
37*bf2c3715SXin Li     deque(const deque& c) : deque_base(c) {}  \
38*bf2c3715SXin Li     explicit deque(size_type num, const value_type& val = value_type()) : deque_base(num, val) {} \
39*bf2c3715SXin Li     deque(iterator start_, iterator end_) : deque_base(start_, end_) {}  \
40*bf2c3715SXin Li     deque& operator=(const deque& x) {  \
41*bf2c3715SXin Li       deque_base::operator=(x);  \
42*bf2c3715SXin Li       return *this;  \
43*bf2c3715SXin Li     } \
44*bf2c3715SXin Li   }; \
45*bf2c3715SXin Li }
46*bf2c3715SXin Li 
47*bf2c3715SXin Li // check whether we really need the std::deque specialization
48*bf2c3715SXin Li #if !EIGEN_HAS_CXX11_CONTAINERS && !(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&). */
49*bf2c3715SXin Li 
50*bf2c3715SXin Li namespace std {
51*bf2c3715SXin Li 
52*bf2c3715SXin Li #define EIGEN_STD_DEQUE_SPECIALIZATION_BODY \
53*bf2c3715SXin Li   public:  \
54*bf2c3715SXin Li     typedef T value_type; \
55*bf2c3715SXin Li     typedef typename deque_base::allocator_type allocator_type; \
56*bf2c3715SXin Li     typedef typename deque_base::size_type size_type;  \
57*bf2c3715SXin Li     typedef typename deque_base::iterator iterator;  \
58*bf2c3715SXin Li     typedef typename deque_base::const_iterator const_iterator;  \
59*bf2c3715SXin Li     explicit deque(const allocator_type& a = allocator_type()) : deque_base(a) {}  \
60*bf2c3715SXin Li     template<typename InputIterator> \
61*bf2c3715SXin Li     deque(InputIterator first, InputIterator last, const allocator_type& a = allocator_type()) \
62*bf2c3715SXin Li     : deque_base(first, last, a) {} \
63*bf2c3715SXin Li     deque(const deque& c) : deque_base(c) {}  \
64*bf2c3715SXin Li     explicit deque(size_type num, const value_type& val = value_type()) : deque_base(num, val) {} \
65*bf2c3715SXin Li     deque(iterator start_, iterator end_) : deque_base(start_, end_) {}  \
66*bf2c3715SXin Li     deque& operator=(const deque& x) {  \
67*bf2c3715SXin Li       deque_base::operator=(x);  \
68*bf2c3715SXin Li       return *this;  \
69*bf2c3715SXin Li     }
70*bf2c3715SXin Li 
71*bf2c3715SXin Li   template<typename T>
72*bf2c3715SXin Li   class deque<T,EIGEN_ALIGNED_ALLOCATOR<T> >
73*bf2c3715SXin Li     : public deque<EIGEN_WORKAROUND_MSVC_STL_SUPPORT(T),
74*bf2c3715SXin Li                    Eigen::aligned_allocator_indirection<EIGEN_WORKAROUND_MSVC_STL_SUPPORT(T)> >
75*bf2c3715SXin Li {
76*bf2c3715SXin Li   typedef deque<EIGEN_WORKAROUND_MSVC_STL_SUPPORT(T),
77*bf2c3715SXin Li                 Eigen::aligned_allocator_indirection<EIGEN_WORKAROUND_MSVC_STL_SUPPORT(T)> > deque_base;
78*bf2c3715SXin Li   EIGEN_STD_DEQUE_SPECIALIZATION_BODY
79*bf2c3715SXin Li 
resize(size_type new_size)80*bf2c3715SXin Li   void resize(size_type new_size)
81*bf2c3715SXin Li   { resize(new_size, T()); }
82*bf2c3715SXin Li 
83*bf2c3715SXin Li #if defined(_DEQUE_)
84*bf2c3715SXin Li   // workaround MSVC std::deque implementation
resize(size_type new_size,const value_type & x)85*bf2c3715SXin Li   void resize(size_type new_size, const value_type& x)
86*bf2c3715SXin Li   {
87*bf2c3715SXin Li     if (deque_base::size() < new_size)
88*bf2c3715SXin Li       deque_base::_Insert_n(deque_base::end(), new_size - deque_base::size(), x);
89*bf2c3715SXin Li     else if (new_size < deque_base::size())
90*bf2c3715SXin Li       deque_base::erase(deque_base::begin() + new_size, deque_base::end());
91*bf2c3715SXin Li   }
push_back(const value_type & x)92*bf2c3715SXin Li   void push_back(const value_type& x)
93*bf2c3715SXin Li   { deque_base::push_back(x); }
push_front(const value_type & x)94*bf2c3715SXin Li   void push_front(const value_type& x)
95*bf2c3715SXin Li   { deque_base::push_front(x); }
96*bf2c3715SXin Li   using deque_base::insert;
insert(const_iterator position,const value_type & x)97*bf2c3715SXin Li   iterator insert(const_iterator position, const value_type& x)
98*bf2c3715SXin Li   { return deque_base::insert(position,x); }
insert(const_iterator position,size_type new_size,const value_type & x)99*bf2c3715SXin Li   void insert(const_iterator position, size_type new_size, const value_type& x)
100*bf2c3715SXin Li   { deque_base::insert(position, new_size, x); }
101*bf2c3715SXin Li #else
102*bf2c3715SXin Li   // default implementation which should always work.
resize(size_type new_size,const value_type & x)103*bf2c3715SXin Li   void resize(size_type new_size, const value_type& x)
104*bf2c3715SXin Li   {
105*bf2c3715SXin Li     if (new_size < deque_base::size())
106*bf2c3715SXin Li       deque_base::erase(deque_base::begin() + new_size, deque_base::end());
107*bf2c3715SXin Li     else if (new_size > deque_base::size())
108*bf2c3715SXin Li       deque_base::insert(deque_base::end(), new_size - deque_base::size(), x);
109*bf2c3715SXin Li   }
110*bf2c3715SXin Li #endif
111*bf2c3715SXin Li   };
112*bf2c3715SXin Li }
113*bf2c3715SXin Li 
114*bf2c3715SXin Li #endif // check whether specialization is actually required
115*bf2c3715SXin Li 
116*bf2c3715SXin Li #endif // EIGEN_STDDEQUE_H
117