10#ifndef XTENSOR_STORAGE_HPP 
   11#define XTENSOR_STORAGE_HPP 
   16#include <initializer_list> 
   21#include "../core/xtensor_config.hpp" 
   22#include "../utils/xexception.hpp" 
   23#include "../utils/xtensor_simd.hpp" 
   24#include "../utils/xutils.hpp" 
   33    template <
class T, 
class A = std::allocator<T>>
 
   38        using allocator_type = A;
 
   40        using value_type = 
typename std::allocator_traits<A>::value_type;
 
   41        using reference = value_type&;
 
   42        using const_reference = 
const value_type&;
 
   43        using pointer = 
typename std::allocator_traits<A>::pointer;
 
   44        using const_pointer = 
typename std::allocator_traits<A>::const_pointer;
 
   46        using size_type = 
typename std::allocator_traits<A>::size_type;
 
   47        using difference_type = 
typename std::allocator_traits<A>::difference_type;
 
   49        using iterator = pointer;
 
   50        using const_iterator = const_pointer;
 
   51        using reverse_iterator = std::reverse_iterator<iterator>;
 
   52        using const_reverse_iterator = std::reverse_iterator<const_iterator>;
 
   55        explicit uvector(
const allocator_type& alloc) 
noexcept;
 
   56        explicit uvector(size_type count, 
const allocator_type& alloc = allocator_type());
 
   57        uvector(size_type count, const_reference value, 
const allocator_type& alloc = allocator_type());
 
   59        template <std::input_iterator InputIt>
 
   60        uvector(InputIt first, InputIt last, 
const allocator_type& alloc = allocator_type());
 
   62        uvector(std::initializer_list<T> init, 
const allocator_type& alloc = allocator_type());
 
   66        uvector(
const uvector& rhs);
 
   67        uvector(
const uvector& rhs, 
const allocator_type& alloc);
 
   68        uvector& operator=(
const uvector&);
 
   70        uvector(uvector&& rhs) 
noexcept;
 
   71        uvector(uvector&& rhs, 
const allocator_type& alloc) 
noexcept;
 
   72        uvector& operator=(uvector&& rhs) 
noexcept;
 
   74        allocator_type get_allocator() 
const noexcept;
 
   76        bool empty() 
const noexcept;
 
   77        size_type size() 
const noexcept;
 
   78        void resize(size_type size);
 
   79        size_type max_size() 
const noexcept;
 
   80        void reserve(size_type new_cap);
 
   81        size_type capacity() 
const noexcept;
 
   85        reference operator[](size_type i);
 
   86        const_reference operator[](size_type i) 
const;
 
   88        reference at(size_type i);
 
   89        const_reference at(size_type i) 
const;
 
   92        const_reference front() 
const;
 
   95        const_reference back() 
const;
 
   97        pointer data() 
noexcept;
 
   98        const_pointer data() 
const noexcept;
 
  100        iterator begin() 
noexcept;
 
  101        iterator end() 
noexcept;
 
  103        const_iterator begin() 
const noexcept;
 
  104        const_iterator end() 
const noexcept;
 
  106        const_iterator cbegin() 
const noexcept;
 
  107        const_iterator cend() 
const noexcept;
 
  109        reverse_iterator rbegin() 
noexcept;
 
  110        reverse_iterator rend() 
noexcept;
 
  112        const_reverse_iterator rbegin() 
const noexcept;
 
  113        const_reverse_iterator rend() 
const noexcept;
 
  115        const_reverse_iterator crbegin() 
const noexcept;
 
  116        const_reverse_iterator crend() 
const noexcept;
 
  118        void swap(uvector& rhs) 
noexcept;
 
  123        void init_data(I first, I last);
 
  125        void resize_impl(size_type new_size);
 
  127        allocator_type m_allocator;
 
 
  135    template <
class T, 
class A>
 
  138    template <
class T, 
class A>
 
  141    template <
class T, 
class A>
 
  144    template <
class T, 
class A>
 
  147    template <
class T, 
class A>
 
  150    template <
class T, 
class A>
 
  153    template <
class T, 
class A>
 
  163        inline typename std::allocator_traits<A>::pointer
 
  164        safe_init_allocate(A& alloc, 
typename std::allocator_traits<A>::size_type size)
 
  166            using traits = std::allocator_traits<A>;
 
  167            using pointer = 
typename traits::pointer;
 
  168            using value_type = 
typename traits::value_type;
 
  169            pointer res = alloc.allocate(size);
 
  170            if (!xtrivially_default_constructible<value_type>::value)
 
  172                for (pointer p = res; p != res + size; ++p)
 
  174                    traits::construct(alloc, p, value_type());
 
  181        inline void safe_destroy_deallocate(
 
  183            typename std::allocator_traits<A>::pointer ptr,
 
  184            typename std::allocator_traits<A>::size_type size
 
  187            using traits = std::allocator_traits<A>;
 
  188            using pointer = 
typename traits::pointer;
 
  189            using value_type = 
typename traits::value_type;
 
  192                if (!xtrivially_default_constructible<value_type>::value)
 
  194                    for (pointer p = ptr; p != ptr + size; ++p)
 
  196                        traits::destroy(alloc, p);
 
  199                traits::deallocate(alloc, ptr, size);
 
  204    template <
class T, 
class A>
 
  206    inline void uvector<T, A>::init_data(I first, I last)
 
  208        size_type size = 
static_cast<size_type
>(std::distance(first, last));
 
  209        if (size != size_type(0))
 
  211            p_begin = m_allocator.allocate(size);
 
  212            std::uninitialized_copy(first, last, p_begin);
 
  213            p_end = p_begin + size;
 
  217    template <
class T, 
class A>
 
  218    inline void uvector<T, A>::resize_impl(size_type new_size)
 
  220        size_type old_size = size();
 
  221        pointer old_begin = p_begin;
 
  222        if (new_size != old_size)
 
  224            p_begin = detail::safe_init_allocate(m_allocator, new_size);
 
  225            p_end = p_begin + new_size;
 
  226            detail::safe_destroy_deallocate(m_allocator, old_begin, old_size);
 
  230    template <
class T, 
class A>
 
  231    inline uvector<T, A>::uvector() noexcept
 
  236    template <
class T, 
class A>
 
  237    inline uvector<T, A>::uvector(
const allocator_type& alloc) noexcept
 
  244    template <
class T, 
class A>
 
  245    inline uvector<T, A>::uvector(size_type count, 
const allocator_type& alloc)
 
  252            p_begin = detail::safe_init_allocate(m_allocator, count);
 
  253            p_end = p_begin + count;
 
  257    template <
class T, 
class A>
 
  258    inline uvector<T, A>::uvector(size_type count, const_reference value, 
const allocator_type& alloc)
 
  265            p_begin = m_allocator.allocate(count);
 
  266            p_end = p_begin + count;
 
  267            std::uninitialized_fill(p_begin, p_end, value);
 
  271    template <
class T, 
class A>
 
  272    template <std::input_iterator InputIt>
 
  273    inline uvector<T, A>::uvector(InputIt first, InputIt last, 
const allocator_type& alloc)
 
  278        init_data(first, last);
 
  281    template <
class T, 
class A>
 
  282    inline uvector<T, A>::uvector(std::initializer_list<T> init, 
const allocator_type& alloc)
 
  287        init_data(init.begin(), init.end());
 
  290    template <
class T, 
class A>
 
  291    inline uvector<T, A>::~uvector()
 
  293        detail::safe_destroy_deallocate(m_allocator, p_begin, size());
 
  298    template <
class T, 
class A>
 
  299    inline uvector<T, A>::uvector(
const uvector& rhs)
 
  301            std::allocator_traits<allocator_type>::select_on_container_copy_construction(rhs.get_allocator())
 
  306        init_data(rhs.p_begin, rhs.p_end);
 
  309    template <
class T, 
class A>
 
  310    inline uvector<T, A>::uvector(
const uvector& rhs, 
const allocator_type& alloc)
 
  315        init_data(rhs.p_begin, rhs.p_end);
 
  318    template <
class T, 
class A>
 
  324            m_allocator = std::allocator_traits<allocator_type>::select_on_container_copy_construction(
 
  327            resize_impl(rhs.size());
 
  328            if (xtrivially_default_constructible<value_type>::value)
 
  330                std::uninitialized_copy(rhs.p_begin, rhs.p_end, p_begin);
 
  334                std::copy(rhs.p_begin, rhs.p_end, p_begin);
 
  340    template <
class T, 
class A>
 
  341    inline uvector<T, A>::uvector(
uvector&& rhs) noexcept
 
  342        : m_allocator(std::move(rhs.m_allocator))
 
  343        , p_begin(rhs.p_begin)
 
  346        rhs.p_begin = 
nullptr;
 
  350    template <
class T, 
class A>
 
  351    inline uvector<T, A>::uvector(
uvector&& rhs, 
const allocator_type& alloc) noexcept
 
  353        , p_begin(rhs.p_begin)
 
  356        rhs.p_begin = 
nullptr;
 
  360    template <
class T, 
class A>
 
  365        swap(p_begin, tmp.p_begin);
 
  366        swap(p_end, tmp.p_end);
 
  370    template <
class T, 
class A>
 
  371    inline auto uvector<T, A>::get_allocator() const noexcept -> allocator_type
 
  373        return allocator_type(m_allocator);
 
  376    template <
class T, 
class A>
 
  377    inline bool uvector<T, A>::empty() const noexcept
 
  379        return size() == size_type(0);
 
  382    template <
class T, 
class A>
 
  383    inline auto uvector<T, A>::size() const noexcept -> size_type
 
  385        return static_cast<size_type
>(p_end - p_begin);
 
  388    template <
class T, 
class A>
 
  389    inline void uvector<T, A>::resize(size_type size)
 
  394    template <
class T, 
class A>
 
  395    inline auto uvector<T, A>::max_size() const noexcept -> size_type
 
  397        return m_allocator.max_size();
 
  400    template <
class T, 
class A>
 
  401    inline void uvector<T, A>::reserve(size_type )
 
  405    template <
class T, 
class A>
 
  406    inline auto uvector<T, A>::capacity() const noexcept -> size_type
 
  411    template <
class T, 
class A>
 
  412    inline void uvector<T, A>::shrink_to_fit()
 
  416    template <
class T, 
class A>
 
  417    inline void uvector<T, A>::clear()
 
  419        resize(size_type(0));
 
  422    template <
class T, 
class A>
 
  423    inline auto uvector<T, A>::operator[](size_type i) -> reference
 
  428    template <
class T, 
class A>
 
  429    inline auto uvector<T, A>::operator[](size_type i) 
const -> const_reference
 
  434    template <
class T, 
class A>
 
  435    inline auto uvector<T, A>::at(size_type i) -> reference
 
  439            XTENSOR_THROW(std::out_of_range, 
"Out of range in uvector access");
 
  441        return this->operator[](i);
 
  444    template <
class T, 
class A>
 
  445    inline auto uvector<T, A>::at(size_type i) 
const -> const_reference
 
  449            XTENSOR_THROW(std::out_of_range, 
"Out of range in uvector access");
 
  451        return this->operator[](i);
 
  454    template <
class T, 
class A>
 
  455    inline auto uvector<T, A>::front() -> reference
 
  460    template <
class T, 
class A>
 
  461    inline auto uvector<T, A>::front() const -> const_reference
 
  466    template <
class T, 
class A>
 
  467    inline auto uvector<T, A>::back() -> reference
 
  472    template <
class T, 
class A>
 
  473    inline auto uvector<T, A>::back() const -> const_reference
 
  478    template <
class T, 
class A>
 
  479    inline auto uvector<T, A>::data() noexcept -> pointer
 
  484    template <
class T, 
class A>
 
  485    inline auto uvector<T, A>::data() const noexcept -> const_pointer
 
  490    template <
class T, 
class A>
 
  491    inline auto uvector<T, A>::begin() noexcept -> iterator
 
  496    template <
class T, 
class A>
 
  497    inline auto uvector<T, A>::end() noexcept -> iterator
 
  502    template <
class T, 
class A>
 
  503    inline auto uvector<T, A>::begin() const noexcept -> const_iterator
 
  508    template <
class T, 
class A>
 
  509    inline auto uvector<T, A>::end() const noexcept -> const_iterator
 
  514    template <
class T, 
class A>
 
  515    inline auto uvector<T, A>::cbegin() const noexcept -> const_iterator
 
  520    template <
class T, 
class A>
 
  521    inline auto uvector<T, A>::cend() const noexcept -> const_iterator
 
  526    template <
class T, 
class A>
 
  527    inline auto uvector<T, A>::rbegin() noexcept -> reverse_iterator
 
  529        return reverse_iterator(end());
 
  532    template <
class T, 
class A>
 
  533    inline auto uvector<T, A>::rend() noexcept -> reverse_iterator
 
  535        return reverse_iterator(begin());
 
  538    template <
class T, 
class A>
 
  539    inline auto uvector<T, A>::rbegin() const noexcept -> const_reverse_iterator
 
  541        return const_reverse_iterator(end());
 
  544    template <
class T, 
class A>
 
  545    inline auto uvector<T, A>::rend() const noexcept -> const_reverse_iterator
 
  547        return const_reverse_iterator(begin());
 
  550    template <
class T, 
class A>
 
  551    inline auto uvector<T, A>::crbegin() const noexcept -> const_reverse_iterator
 
  556    template <
class T, 
class A>
 
  557    inline auto uvector<T, A>::crend() const noexcept -> const_reverse_iterator
 
  562    template <
class T, 
class A>
 
  566        swap(m_allocator, rhs.m_allocator);
 
  567        swap(p_begin, rhs.p_begin);
 
  568        swap(p_end, rhs.p_end);
 
  571    template <
class T, 
class A>
 
  574        return lhs.size() == rhs.size() && std::equal(lhs.begin(), lhs.end(), rhs.begin());
 
  577    template <
class T, 
class A>
 
  580        return !(lhs == rhs);
 
  583    template <
class T, 
class A>
 
  586        return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
 
  589    template <
class T, 
class A>
 
  595    template <
class T, 
class A>
 
  601    template <
class T, 
class A>
 
  607    template <
class T, 
class A>
 
  620        struct allocator_alignment
 
  622            static constexpr std::size_t value = 0;
 
  625        template <
class T, std::
size_t A>
 
  626        struct allocator_alignment<xt_simd::aligned_allocator<T, A>>
 
  628            static constexpr std::size_t value = A;
 
  632    template <
class T, std::
size_t N = 4, 
class A = std::allocator<T>, 
bool Init = true>
 
  637        using self_type = svector<T, N, A, Init>;
 
  638        using allocator_type = A;
 
  639        using size_type = 
typename std::allocator_traits<A>::size_type;
 
  640        using value_type = 
typename std::allocator_traits<A>::value_type;
 
  641        using pointer = 
typename std::allocator_traits<A>::pointer;
 
  642        using const_pointer = 
typename std::allocator_traits<A>::const_pointer;
 
  643        using reference = value_type&;
 
  644        using const_reference = 
const value_type&;
 
  645        using difference_type = 
typename std::allocator_traits<A>::difference_type;
 
  647        using iterator = pointer;
 
  648        using const_iterator = const_pointer;
 
  649        using reverse_iterator = std::reverse_iterator<iterator>;
 
  650        using const_reverse_iterator = std::reverse_iterator<const_iterator>;
 
  652#if defined(_MSC_VER) && _MSC_VER < 1910 
  653        static constexpr std::size_t alignment = detail::allocator_alignment<A>::value;
 
  655        static constexpr std::size_t alignment = detail::allocator_alignment<A>::value != 0
 
  656                                                     ? detail::allocator_alignment<A>::value
 
  663        explicit svector(
const allocator_type& alloc) 
noexcept;
 
  664        explicit svector(size_type n, 
const allocator_type& alloc = allocator_type());
 
  665        svector(size_type n, 
const value_type& v, 
const allocator_type& alloc = allocator_type());
 
  666        svector(std::initializer_list<T> il, 
const allocator_type& alloc = allocator_type());
 
  668        svector(
const std::vector<T>& vec);
 
  670        template <std::input_iterator IT>
 
  671        svector(IT begin, IT end, 
const allocator_type& alloc = allocator_type());
 
  673        template <std::
size_t N2, 
bool I2>
 
  674        explicit svector(
const svector<T, N2, A, I2>& rhs)
 
  677        svector& operator=(
const svector& rhs);
 
  678        svector& operator=(svector&& rhs) 
noexcept(std::is_nothrow_move_assignable<value_type>::value);
 
  679        svector& operator=(
const std::vector<T>& rhs);
 
  680        svector& operator=(std::initializer_list<T> il);
 
  682        template <std::
size_t N2, 
bool I2>
 
  683        svector& operator=(
const svector<T, N2, A, I2>& rhs)
 
  686        svector(
const svector& other);
 
  687        svector(svector&& other) 
noexcept(std::is_nothrow_move_constructible<value_type>::value);
 
  689        void assign(size_type n, 
const value_type& v);
 
  692        void assign(std::initializer_list<V> il);
 
  695        void assign(IT other_begin, IT other_end);
 
  697        reference operator[](size_type idx);
 
  698        const_reference operator[](size_type idx) 
const;
 
  700        reference at(size_type idx);
 
  701        const_reference at(size_type idx) 
const;
 
  704        const_pointer data() 
const;
 
  706        void push_back(
const T& elt);
 
  707        void push_back(T&& elt);
 
  711        const_iterator begin() 
const;
 
  712        const_iterator cbegin() 
const;
 
  714        const_iterator end() 
const;
 
  715        const_iterator cend() 
const;
 
  717        reverse_iterator rbegin();
 
  718        const_reverse_iterator rbegin() 
const;
 
  719        const_reverse_iterator crbegin() 
const;
 
  720        reverse_iterator rend();
 
  721        const_reverse_iterator rend() 
const;
 
  722        const_reverse_iterator crend() 
const;
 
  725        size_type size() 
const;
 
  726        void resize(size_type n);
 
  727        size_type max_size() 
const noexcept;
 
  728        size_type capacity() 
const;
 
  729        void reserve(size_type n);
 
  730        void shrink_to_fit();
 
  734        const_reference front() 
const;
 
  736        const_reference back() 
const;
 
  740        iterator erase(const_iterator cit);
 
  741        iterator erase(const_iterator cfirst, const_iterator clast);
 
  743        iterator insert(const_iterator it, 
const T& elt);
 
  746        iterator insert(const_iterator pos, It first, It last);
 
  748        iterator insert(const_iterator pos, std::initializer_list<T> l);
 
  750        template <std::
size_t ON, 
class OA, 
bool InitA>
 
  751        void swap(svector<T, ON, OA, InitA>& rhs);
 
  753        allocator_type get_allocator() 
const noexcept;
 
  759        T* m_begin = std::begin(m_data);
 
  760        T* m_end = std::begin(m_data);
 
  761        T* m_capacity = std::end(m_data);
 
  764        alignas(alignment) T m_data[N > 0 ? N : 1];
 
  766        void grow(size_type min_capacity = 0);
 
  767        void destroy_range(T* begin, T* end);
 
 
  770    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
  771    inline svector<T, N, A, Init>::~svector()
 
  775            detail::safe_destroy_deallocate(m_allocator, m_begin, 
static_cast<std::size_t
>(m_capacity - m_begin));
 
  779    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
  780    inline svector<T, N, A, Init>::svector() noexcept
 
  785    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
  786    inline svector<T, N, A, Init>::svector(
const allocator_type& alloc) noexcept
 
  791    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
  792    inline svector<T, N, A, Init>::svector(size_type n, 
const allocator_type& alloc)
 
  805    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
  806    template <std::input_iterator IT>
 
  807    inline svector<T, N, A, Init>::svector(IT begin, IT end, 
const allocator_type& alloc)
 
  813    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
  814    template <std::
size_t N2, 
bool I2>
 
  817        : m_allocator(rhs.get_allocator())
 
  819        assign(rhs.begin(), rhs.end());
 
  822    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
  823    inline svector<T, N, A, Init>::svector(
const std::vector<T>& vec)
 
  825        assign(vec.begin(), vec.end());
 
  828    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
  829    inline svector<T, N, A, Init>::svector(size_type n, 
const value_type& v, 
const allocator_type& alloc)
 
  835    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
  836    inline svector<T, N, A, Init>::svector(std::initializer_list<T> il, 
const allocator_type& alloc)
 
  839        assign(il.begin(), il.end());
 
  842    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
  845        assign(rhs.begin(), rhs.end());
 
  849    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
  851    ) 
noexcept(std::is_nothrow_move_assignable<value_type>::value)
 
  853        assign(rhs.begin(), rhs.end());
 
  857    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
  860        m_allocator = std::allocator_traits<allocator_type>::select_on_container_copy_construction(
 
  863        assign(rhs.begin(), rhs.end());
 
  867    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
  870        return operator=(self_type(il));
 
  873    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
  874    template <std::
size_t N2, 
bool I2>
 
  878        m_allocator = std::allocator_traits<allocator_type>::select_on_container_copy_construction(
 
  881        assign(rhs.begin(), rhs.end());
 
  885    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
  886    inline svector<T, N, A, Init>::svector(
const svector& rhs)
 
  888            std::allocator_traits<allocator_type>::select_on_container_copy_construction(rhs.get_allocator())
 
  891        assign(rhs.begin(), rhs.end());
 
  894    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
  895    inline svector<T, N, A, Init>::svector(
svector&& rhs
 
  896    ) 
noexcept(std::is_nothrow_move_constructible<value_type>::value)
 
  901    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
  902    inline void svector<T, N, A, Init>::assign(size_type n, 
const value_type& v)
 
  904        if (n > N && n > capacity())
 
  909        std::fill(begin(), end(), v);
 
  912    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
  914    inline void svector<T, N, A, Init>::assign(std::initializer_list<V> il)
 
  916        assign(il.begin(), il.end());
 
  919    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
  921    inline void svector<T, N, A, Init>::assign(IT other_begin, IT other_end)
 
  923        std::size_t size = 
static_cast<std::size_t
>(other_end - other_begin);
 
  924        if (size > N && size > capacity())
 
  928        std::uninitialized_copy(other_begin, other_end, m_begin);
 
  929        m_end = m_begin + size;
 
  932    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
  933    inline auto svector<T, N, A, Init>::operator[](size_type idx) -> reference
 
  938    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
  939    inline auto svector<T, N, A, Init>::operator[](size_type idx) 
const -> const_reference
 
  944    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
  945    inline auto svector<T, N, A, Init>::at(size_type idx) -> reference
 
  949            XTENSOR_THROW(std::out_of_range, 
"Out of range in svector access");
 
  951        return this->operator[](idx);
 
  954    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
  955    inline auto svector<T, N, A, Init>::at(size_type idx) 
const -> const_reference
 
  959            XTENSOR_THROW(std::out_of_range, 
"Out of range in svector access");
 
  961        return this->operator[](idx);
 
  964    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
  965    inline auto svector<T, N, A, Init>::data() -> pointer
 
  970    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
  971    inline auto svector<T, N, A, Init>::data() const -> const_pointer
 
  976    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
  977    void svector<T, N, A, Init>::resize(size_type n)
 
  979        if (n > N && n > capacity())
 
  983        size_type old_size = size();
 
  985        if (Init && old_size < size())
 
  987            std::fill(begin() + old_size, end(), T());
 
  991    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
  992    inline auto svector<T, N, A, Init>::max_size() const noexcept -> size_type
 
  994        return m_allocator.max_size();
 
  997    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
  998    inline auto svector<T, N, A, Init>::capacity() const -> size_type
 
 1000        return static_cast<std::size_t
>(m_capacity - m_begin);
 
 1003    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
 1004    inline void svector<T, N, A, Init>::reserve(size_type n)
 
 1006        if (n > N && n > capacity())
 
 1012    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
 1013    inline void svector<T, N, A, Init>::shrink_to_fit()
 
 1018    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
 1019    inline void svector<T, N, A, Init>::clear()
 
 1021        resize(size_type(0));
 
 1024    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
 1025    void svector<T, N, A, Init>::push_back(
const T& elt)
 
 1027        if (m_end >= m_capacity)
 
 1034    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
 1035    void svector<T, N, A, Init>::push_back(T&& elt)
 
 1037        if (m_end >= m_capacity)
 
 1041        *(m_end++) = std::move(elt);
 
 1044    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
 1045    void svector<T, N, A, Init>::pop_back()
 
 1050    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
 1051    inline auto svector<T, N, A, Init>::begin() -> iterator
 
 1056    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
 1057    inline auto svector<T, N, A, Init>::begin() const -> const_iterator
 
 1062    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
 1063    inline auto svector<T, N, A, Init>::cbegin() const -> const_iterator
 
 1068    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
 1069    inline auto svector<T, N, A, Init>::end() -> iterator
 
 1074    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
 1075    inline auto svector<T, N, A, Init>::end() const -> const_iterator
 
 1080    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
 1081    inline auto svector<T, N, A, Init>::cend() const -> const_iterator
 
 1086    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
 1087    inline auto svector<T, N, A, Init>::rbegin() -> reverse_iterator
 
 1089        return reverse_iterator(m_end);
 
 1092    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
 1093    inline auto svector<T, N, A, Init>::rbegin() const -> const_reverse_iterator
 
 1095        return const_reverse_iterator(m_end);
 
 1098    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
 1099    inline auto svector<T, N, A, Init>::crbegin() const -> const_reverse_iterator
 
 1101        return const_reverse_iterator(m_end);
 
 1104    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
 1105    inline auto svector<T, N, A, Init>::rend() -> reverse_iterator
 
 1107        return reverse_iterator(m_begin);
 
 1110    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
 1111    inline auto svector<T, N, A, Init>::rend() const -> const_reverse_iterator
 
 1113        return const_reverse_iterator(m_begin);
 
 1116    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
 1117    inline auto svector<T, N, A, Init>::crend() const -> const_reverse_iterator
 
 1119        return const_reverse_iterator(m_begin);
 
 1122    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
 1123    inline auto svector<T, N, A, Init>::size() const -> size_type
 
 1125        return static_cast<size_type
>(m_end - m_begin);
 
 1128    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
 1129    inline auto svector<T, N, A, Init>::empty() const -> 
bool 
 1131        return m_begin == m_end;
 
 1134    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
 1135    inline auto svector<T, N, A, Init>::front() -> reference
 
 1137        XTENSOR_ASSERT(!
empty());
 
 1141    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
 1142    inline auto svector<T, N, A, Init>::front() const -> const_reference
 
 1144        XTENSOR_ASSERT(!
empty());
 
 1148    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
 1149    inline auto svector<T, N, A, Init>::back() -> reference
 
 1151        XTENSOR_ASSERT(!
empty());
 
 1155    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
 1156    inline auto svector<T, N, A, Init>::back() const -> const_reference
 
 1158        XTENSOR_ASSERT(!
empty());
 
 1162    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
 1163    inline auto svector<T, N, A, Init>::on_stack() -> 
bool 
 1165        return m_begin == &m_data[0];
 
 1168    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
 1169    inline auto svector<T, N, A, Init>::get_allocator() const noexcept -> allocator_type
 
 1174    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
 1175    inline auto svector<T, N, A, Init>::erase(const_iterator cit) -> iterator
 
 1177        auto it = 
const_cast<pointer
>(cit);
 
 1178        iterator ret_val = it;
 
 1179        std::move(it + 1, m_end, it);
 
 1184    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
 1185    inline auto svector<T, N, A, Init>::erase(const_iterator cfirst, const_iterator clast) -> iterator
 
 1187        auto first = 
const_cast<pointer
>(cfirst);
 
 1188        auto last = 
const_cast<pointer
>(clast);
 
 1195        iterator new_end = std::move(last, m_end, first);
 
 1200    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
 1201    inline auto svector<T, N, A, Init>::insert(const_iterator cit, 
const T& elt) -> iterator
 
 1203        auto it = 
const_cast<pointer
>(cit);
 
 1210        if (m_end >= m_capacity)
 
 1212            std::ptrdiff_t elt_no = it - m_begin;
 
 1214            it = m_begin + elt_no;
 
 1218        std::move_backward(it, m_end - 1, m_end);
 
 1222        const T* elt_ptr = &elt;
 
 1223        bool cond = it <= elt_ptr && elt_ptr < m_end;
 
 1226        const T* src_ptr = cond ? it + (elt_ptr - it) + std::ptrdiff_t(1) : elt_ptr;
 
 1231    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
 1233    inline auto svector<T, N, A, Init>::insert(const_iterator pos, It first, It last) -> iterator
 
 1235        auto it = 
const_cast<pointer
>(pos);
 
 1236        difference_type n = std::distance(first, last);
 
 1239            if (n > m_capacity - m_end)
 
 1241                std::ptrdiff_t elt_no = it - m_begin;
 
 1242                grow(
static_cast<size_t>((m_capacity - m_begin) + n));
 
 1243                it = m_begin + elt_no;
 
 1246            std::move_backward(it, m_end, m_end + n);
 
 1248            std::copy(first, last, it);
 
 1253    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
 1254    inline auto svector<T, N, A, Init>::insert(const_iterator pos, std::initializer_list<T> l) -> iterator
 
 1256        return insert(pos, l.begin(), l.end());
 
 1259    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
 1260    inline void svector<T, N, A, Init>::destroy_range(T* begin, T* end)
 
 1262        if (!xtrivially_default_constructible<T>::value)
 
 1264            while (begin != end)
 
 1272    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
 1273    template <std::
size_t ON, 
class OA, 
bool InitA>
 
 1283        if (!this->on_stack() && !rhs.on_stack())
 
 1285            swap(this->m_begin, rhs.m_begin);
 
 1286            swap(this->m_end, rhs.m_end);
 
 1287            swap(this->m_capacity, rhs.m_capacity);
 
 1291        size_type rhs_old_size = rhs.size();
 
 1292        size_type old_size = this->size();
 
 1294        if (rhs_old_size > old_size)
 
 1296            this->resize(rhs_old_size);
 
 1298        else if (old_size > rhs_old_size)
 
 1300            rhs.resize(old_size);
 
 1304        size_type min_size = (std::min)(old_size, rhs_old_size);
 
 1305        for (size_type i = 0; i < min_size; ++i)
 
 1307            swap((*
this)[i], rhs[i]);
 
 1311        if (old_size > rhs_old_size)
 
 1313            std::copy(this->begin() + min_size, this->end(), rhs.begin() + min_size);
 
 1314            this->destroy_range(this->begin() + min_size, this->end());
 
 1315            this->m_end = this->begin() + min_size;
 
 1317        else if (rhs_old_size > old_size)
 
 1319            std::copy(rhs.begin() + min_size, rhs.end(), this->begin() + min_size);
 
 1320            this->destroy_range(rhs.begin() + min_size, rhs.end());
 
 1321            rhs.m_end = rhs.begin() + min_size;
 
 1325    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
 1326    inline void svector<T, N, A, Init>::grow(size_type min_capacity)
 
 1328        size_type current_size = size();
 
 1329        size_type new_capacity = 2 * current_size + 1;  
 
 1330        if (new_capacity < min_capacity)
 
 1332            new_capacity = min_capacity;
 
 1337        if (m_begin == &m_data[0])
 
 1339            new_alloc = m_allocator.allocate(new_capacity);
 
 1340            std::uninitialized_copy(m_begin, m_end, new_alloc);
 
 1345            new_alloc = m_allocator.allocate(new_capacity);
 
 1346            std::uninitialized_copy(m_begin, m_end, new_alloc);
 
 1347            m_allocator.deallocate(m_begin, std::size_t(m_capacity - m_begin));
 
 1349        XTENSOR_ASSERT(new_alloc);
 
 1351        m_end = new_alloc + current_size;
 
 1352        m_begin = new_alloc;
 
 1353        m_capacity = new_alloc + new_capacity;
 
 1356    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
 1359        return lhs.size() == rhs.size() && std::equal(lhs.begin(), lhs.end(), rhs.begin());
 
 1362    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
 1365        return lhs.size() == rhs.size() && std::equal(lhs.begin(), lhs.end(), rhs.begin());
 
 1368    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
 1371        return lhs.size() == rhs.size() && std::equal(lhs.begin(), lhs.end(), rhs.begin());
 
 1374    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
 1377        return !(lhs == rhs);
 
 1380    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
 1383        return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
 
 1386    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
 1389        return !(lhs > rhs);
 
 1392    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
 1398    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
 1401        return !(lhs < rhs);
 
 1404    template <
class T, std::
size_t N, 
class A, 
bool Init>
 
 1410    template <
class X, 
class T, std::
size_t N, 
class A, 
bool B>
 
 1413        using traits = std::allocator_traits<A>;
 
 1414        using allocator = 
typename traits::template rebind_alloc<X>;
 
 
 1424    template <
class T, std::
size_t N, std::
size_t Align = XTENSOR_
SELECT_ALIGN(T)>
 
 1431        using allocator_type = std::conditional_t<Align != 0, xt_simd::aligned_allocator<T, Align>, std::allocator<T>>;
 
 
 1434#if defined(_MSC_VER) 
 1435#define XTENSOR_CONST 
 1437#define XTENSOR_CONST const 
 1440#if defined(__GNUC__) && __GNUC__ < 5 && !defined(__clang__) 
 1441#define GCC4_FALLBACK 
 1443    namespace const_array_detail
 
 1445        template <
class T, std::
size_t N>
 
 1448            using storage_type = T[N];
 
 1450            static constexpr T& ref(
const storage_type& t, std::size_t n) 
noexcept 
 1452                return const_cast<T&
>(t[n]);
 
 1455            static constexpr T* ptr(
const storage_type& t) 
noexcept 
 1457                return const_cast<T*
>(t);
 
 1462        struct array_traits<T, 0>
 
 1468            using storage_type = 
empty;
 
 1470            static constexpr T& ref(
const storage_type& , std::size_t ) 
noexcept 
 1472                return *
static_cast<T*
>(
nullptr);
 
 1475            static constexpr T* ptr(
const storage_type& ) 
noexcept 
 1487    template <
class T, std::
size_t N>
 
 1490        using size_type = std::size_t;
 
 1491        using value_type = T;
 
 1492        using pointer = value_type*;
 
 1493        using const_pointer = 
const value_type*;
 
 1494        using reference = value_type&;
 
 1495        using const_reference = 
const value_type&;
 
 1496        using difference_type = std::ptrdiff_t;
 
 1497        using iterator = pointer;
 
 1498        using const_iterator = const_pointer;
 
 1500        using reverse_iterator = std::reverse_iterator<const_iterator>;
 
 1501        using const_reverse_iterator = std::reverse_iterator<const_iterator>;
 
 1503        constexpr const_reference operator[](std::size_t idx)
 const 
 1506            return const_array_detail::array_traits<T, N>::ref(m_data, idx);
 
 1512        constexpr const_iterator begin() 
const noexcept 
 1517        constexpr const_iterator end() 
const noexcept 
 1522        constexpr const_iterator cbegin() 
const noexcept 
 1527        constexpr const_iterator cend() 
const noexcept 
 1533        reverse_iterator rbegin() 
const noexcept 
 1538        reverse_iterator rend() 
const noexcept 
 1543        const_reverse_iterator crbegin() 
const noexcept 
 1545            return const_reverse_iterator(end());
 
 1548        const_reverse_iterator crend() 
const noexcept 
 1550            return const_reverse_iterator(begin());
 
 1553        constexpr const_pointer data() 
const noexcept 
 1556            return const_array_detail::array_traits<T, N>::ptr(m_data);
 
 1562        constexpr const_reference front() 
const noexcept 
 1565            return const_array_detail::array_traits<T, N>::ref(m_data, 0);
 
 1571        constexpr const_reference back() 
const noexcept 
 1574            return N ? const_array_detail::array_traits<T, N>::ref(m_data, N - 1)
 
 1575                     : const_array_detail::array_traits<T, N>::ref(m_data, 0);
 
 1577            return m_data[size() - 1];
 
 1581        constexpr bool empty() 
const noexcept 
 1583            return size() == size_type(0);
 
 1586        constexpr size_type size() 
const noexcept 
 1592        XTENSOR_CONST 
typename const_array_detail::array_traits<T, N>::storage_type m_data;
 
 1594        XTENSOR_CONST T m_data[N > 0 ? N : 1];
 
 
 1600    template <
class T, std::
size_t N>
 
 1603        return std::equal(lhs.cbegin(), lhs.cend(), rhs.cbegin());
 
 1606    template <
class T, std::
size_t N>
 
 1607    inline bool operator!=(
const const_array<T, N>& lhs, 
const const_array<T, N>& rhs)
 
 1609        return !(lhs == rhs);
 
 1612    template <
class T, std::
size_t N>
 
 1613    inline bool operator<(
const const_array<T, N>& lhs, 
const const_array<T, N>& rhs)
 
 1615        return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
 
 1618    template <
class T, std::
size_t N>
 
 1619    inline bool operator<=(
const const_array<T, N>& lhs, 
const const_array<T, N>& rhs)
 
 1621        return !(lhs > rhs);
 
 1624    template <
class T, std::
size_t N>
 
 1625    inline bool operator>(
const const_array<T, N>& lhs, 
const const_array<T, N>& rhs)
 
 1630    template <
class T, std::
size_t N>
 
 1631    inline bool operator>=(
const const_array<T, N>& lhs, 
const const_array<T, N>& rhs)
 
 1633        return !(lhs < rhs);
 
 1637#ifdef __cpp_template_template_args 
 1638    template <
class X, 
class T, std::
size_t N>
 
 1639    struct rebind_container<X, aligned_array<T, N>>
 
 1641        using type = aligned_array<X, N>;
 
 1644    template <
class X, 
class T, std::
size_t N>
 
 1645    struct rebind_container<X, const_array<T, N>>
 
 1647        using type = const_array<X, N>;
 
 1656    template <std::size_t... X>
 
 1661#if defined(_MSC_VER) 
 1662        using cast_type = std::array<std::size_t, 
sizeof...(X)>;
 
 1663#define XTENSOR_FIXED_SHAPE_CONSTEXPR inline 
 1665        using cast_type = 
const_array<std::size_t, 
sizeof...(X)>;
 
 1666#define XTENSOR_FIXED_SHAPE_CONSTEXPR constexpr 
 1668        using value_type = std::size_t;
 
 1669        using size_type = std::size_t;
 
 1670        using const_iterator = 
typename cast_type::const_iterator;
 
 1672        static constexpr std::size_t size()
 
 1674            return sizeof...(X);
 
 1677        template <std::
size_t idx>
 
 1678        static constexpr auto get()
 
 1680            using tmp_cast_type = std::array<std::size_t, 
sizeof...(X)>;
 
 1681            return std::get<idx>(tmp_cast_type{X...});
 
 1684        XTENSOR_FIXED_SHAPE_CONSTEXPR 
operator cast_type()
 const 
 1686            return cast_type({X...});
 
 1689        XTENSOR_FIXED_SHAPE_CONSTEXPR 
auto begin()
 const 
 1691            return m_array.begin();
 
 1694        XTENSOR_FIXED_SHAPE_CONSTEXPR 
auto end()
 const 
 1696            return m_array.end();
 
 1701            return m_array.rbegin();
 
 1706            return m_array.rend();
 
 1709        XTENSOR_FIXED_SHAPE_CONSTEXPR 
auto cbegin()
 const 
 1711            return m_array.cbegin();
 
 1714        XTENSOR_FIXED_SHAPE_CONSTEXPR 
auto cend()
 const 
 1716            return m_array.cend();
 
 1719        XTENSOR_FIXED_SHAPE_CONSTEXPR std::size_t operator[](std::size_t idx)
 const 
 1721            return m_array[idx];
 
 1724        XTENSOR_FIXED_SHAPE_CONSTEXPR 
bool empty()
 const 
 1726            return sizeof...(X) == 0;
 
 1731        XTENSOR_CONSTEXPR_ENHANCED_STATIC cast_type m_array = cast_type({X...});
 
 
 1734#undef XTENSOR_FIXED_SHAPE_CONSTEXPR 
 1736    template <
class E, std::ptrdiff_t Start, std::ptrdiff_t End = -1>
 
 1741        using value_type = 
typename E::value_type;
 
 1742        using reference = 
typename E::reference;
 
 1743        using const_reference = 
typename E::const_reference;
 
 1744        using pointer = 
typename E::pointer;
 
 1745        using const_pointer = 
typename E::const_pointer;
 
 1747        using size_type = 
typename E::size_type;
 
 1748        using difference_type = 
typename E::difference_type;
 
 1750        using iterator = 
typename E::iterator;
 
 1751        using const_iterator = 
typename E::const_iterator;
 
 1752        using reverse_iterator = 
typename E::reverse_iterator;
 
 1753        using const_reverse_iterator = 
typename E::const_reverse_iterator;
 
 1755        explicit sequence_view(
const E& container);
 
 1757        template <std::ptrdiff_t OS, std::ptrdiff_t OE>
 
 1758        explicit sequence_view(
const sequence_view<E, OS, OE>& other);
 
 1760        template <class T, class R = decltype(std::declval<T>().begin())>
 
 1764        size_type size() 
const;
 
 1765        const_reference operator[](std::size_t idx) 
const;
 
 1767        const_iterator end() 
const;
 
 1768        const_iterator begin() 
const;
 
 1769        const_iterator cend() 
const;
 
 1770        const_iterator cbegin() 
const;
 
 1772        const_reverse_iterator rend() 
const;
 
 1773        const_reverse_iterator rbegin() 
const;
 
 1774        const_reverse_iterator crend() 
const;
 
 1775        const_reverse_iterator crbegin() 
const;
 
 1777        const_reference front() 
const;
 
 1778        const_reference back() 
const;
 
 1780        const E& storage() 
const;
 
 1784        const E& m_sequence;
 
 
 1787    template <
class E, std::ptrdiff_t Start, std::ptrdiff_t End>
 
 1788    sequence_view<E, Start, End>::sequence_view(
const E& container)
 
 1789        : m_sequence(container)
 
 1793    template <
class E, std::ptrdiff_t Start, std::ptrdiff_t End>
 
 1794    template <std::ptrdiff_t OS, std::ptrdiff_t OE>
 
 1795    sequence_view<E, Start, End>::sequence_view(
const sequence_view<E, OS, OE>& other)
 
 1796        : m_sequence(other.storage())
 
 1800    template <
class E, std::ptrdiff_t Start, std::ptrdiff_t End>
 
 1801    template <
class T, 
class R>
 
 1804        T ret = xtl::make_sequence<T>(this->size());
 
 1805        std::copy(this->cbegin(), this->cend(), ret.begin());
 
 1809    template <
class E, std::ptrdiff_t Start, std::ptrdiff_t End>
 
 1810    bool sequence_view<E, Start, End>::empty()
 const 
 1812        return size() == size_type(0);
 
 1815    template <
class E, std::ptrdiff_t Start, std::ptrdiff_t End>
 
 1816    auto sequence_view<E, Start, End>::size() const -> size_type
 
 1820            return m_sequence.size() - 
static_cast<size_type
>(Start);
 
 1824            return static_cast<size_type
>(End - Start);
 
 1828    template <
class E, std::ptrdiff_t Start, std::ptrdiff_t End>
 
 1829    auto sequence_view<E, Start, End>::operator[](std::size_t idx) 
const -> const_reference
 
 1831        return m_sequence[idx + 
static_cast<std::size_t
>(Start)];
 
 1834    template <
class E, std::ptrdiff_t Start, std::ptrdiff_t End>
 
 1835    auto sequence_view<E, Start, End>::end() const -> const_iterator
 
 1839            return m_sequence.begin() + End;
 
 1843            return m_sequence.end();
 
 1847    template <
class E, std::ptrdiff_t Start, std::ptrdiff_t End>
 
 1848    auto sequence_view<E, Start, End>::begin() const -> const_iterator
 
 1850        return m_sequence.begin() + Start;
 
 1853    template <
class E, std::ptrdiff_t Start, std::ptrdiff_t End>
 
 1854    auto sequence_view<E, Start, End>::cend() const -> const_iterator
 
 1859    template <
class E, std::ptrdiff_t Start, std::ptrdiff_t End>
 
 1860    auto sequence_view<E, Start, End>::cbegin() const -> const_iterator
 
 1865    template <
class E, std::ptrdiff_t Start, std::ptrdiff_t End>
 
 1866    auto sequence_view<E, Start, End>::rend() const -> const_reverse_iterator
 
 1868        return const_reverse_iterator(begin());
 
 1871    template <
class E, std::ptrdiff_t Start, std::ptrdiff_t End>
 
 1872    auto sequence_view<E, Start, End>::rbegin() const -> const_reverse_iterator
 
 1874        return const_reverse_iterator(end());
 
 1877    template <
class E, std::ptrdiff_t Start, std::ptrdiff_t End>
 
 1878    auto sequence_view<E, Start, End>::crend() const -> const_reverse_iterator
 
 1883    template <
class E, std::ptrdiff_t Start, std::ptrdiff_t End>
 
 1884    auto sequence_view<E, Start, End>::crbegin() const -> const_reverse_iterator
 
 1889    template <
class E, std::ptrdiff_t Start, std::ptrdiff_t End>
 
 1890    auto sequence_view<E, Start, End>::front() const -> const_reference
 
 1892        return *(m_sequence.begin() + Start);
 
 1895    template <
class E, std::ptrdiff_t Start, std::ptrdiff_t End>
 
 1896    auto sequence_view<E, Start, End>::back() const -> const_reference
 
 1900            return m_sequence.back();
 
 1904            return m_sequence[
static_cast<std::size_t
>(End - 1)];
 
 1908    template <
class E, std::ptrdiff_t Start, std::ptrdiff_t End>
 
 1909    const E& sequence_view<E, Start, End>::storage()
 const 
 1914    template <
class T, std::ptrdiff_t TB, std::ptrdiff_t TE>
 
 1917        return lhs.size() == rhs.size() && std::equal(lhs.begin(), lhs.end(), rhs.begin());
 
 1920    template <
class T, std::ptrdiff_t TB, std::ptrdiff_t TE>
 
 1923        return !(lhs == rhs);
 
 1937#if defined(__clang__) 
 1938 # pragma clang diagnostic push 
 1939 # pragma clang diagnostic ignored "-Wmismatched-tags" 
 1945    template <
class T, std::
size_t N>
 
 1946    class tuple_size<
xt::const_array<T, N>> : 
public integral_constant<std::size_t, N>
 
 
 1950    template <std::size_t... N>
 
 1951    class tuple_size<
xt::fixed_shape<N...>> : 
public integral_constant<std::size_t, sizeof...(N)>
 
 
 1955    template <
class T, std::ptrdiff_t Start, std::ptrdiff_t End>
 
 1956    class tuple_size<
xt::sequence_view<T, Start, End>>
 
 1957        : 
public integral_constant<std::size_t, std::size_t(End - Start)>
 
 
 1962    template <
class T, std::ptrdiff_t Start>
 
 1963    class tuple_size<
xt::sequence_view<T, Start, -1>>;
 
 1968#if defined(__clang__) 
 1969 # pragma clang diagnostic pop 
This array class is modeled after std::array but adds optional alignment through a template parameter...
Fixed shape implementation for compile time defined arrays.
standard mathematical functions for xexpressions
xarray< T, L > empty(const S &shape)
Create a xcontainer (xarray, xtensor or xtensor_fixed) with uninitialized values of with value_type T...
A std::array like class with all member function (except reverse iterators) as constexpr.