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