diff --git a/Eigen/src/Core/Stride.h b/Eigen/src/Core/Stride.h new file mode 100644 index 000000000..ba0b19de3 --- /dev/null +++ b/Eigen/src/Core/Stride.h @@ -0,0 +1,136 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2010 Benoit Jacob +// +// Eigen is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 3 of the License, or (at your option) any later version. +// +// Alternatively, you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of +// the License, or (at your option) any later version. +// +// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License and a copy of the GNU General Public License along with +// Eigen. If not, see . + +#ifndef EIGEN_STRIDE_H +#define EIGEN_STRIDE_H + +template +class Stride +{ + public: + + enum { + InnerStrideAtCompileTime = _InnerStrideAtCompileTime, + OuterStrideAtCompileTime = _OuterStrideAtCompileTime + }; + + Stride() + : m_inner(InnerStrideAtCompileTime), m_outer(OuterStrideAtCompileTime) + { + ei_assert(InnerStrideAtCompileTime != Dynamic && OuterStrideAtCompileTime != Dynamic); + } + + Stride(int innerStride, int outerStride) + : m_inner(innerStride), m_outer(outerStride) + { + ei_assert(innerStride>=0 && outerStride>=0); + } + + Stride(const Stride& other) + : m_inner(other.inner()), m_outer(other.outer()) + {} + + inline int inner() const { return m_inner.value(); } + inline int outer() const { return m_outer.value(); } + + template + Stride + operator|(const Stride& other) + { + EIGEN_STATIC_ASSERT(!((InnerStrideAtCompileTime && OtherInnerStrideAtCompileTime) + || (OuterStrideAtCompileTime && OtherOuterStrideAtCompileTime)), + YOU_ALREADY_SPECIFIED_THIS_STRIDE) + int result_inner = InnerStrideAtCompileTime ? inner() : other.inner(); + int result_outer = OuterStrideAtCompileTime ? outer() : other.outer(); + return Stride + (result_inner, result_outer); + } + protected: + ei_int_if_dynamic m_inner; + ei_int_if_dynamic m_outer; +}; + +template +class InnerStride : public Stride +{ + typedef Stride Base; + public: + InnerStride() : Base() {} + InnerStride(int v) : Base(v,0) {} +}; + +template +class OuterStride : public Stride<0, Value> +{ + typedef Stride<0,Value> Base; + public: + OuterStride() : Base() {} + OuterStride(int v) : Base(0,v) {} +}; + +template::Flags)&DirectAccessBit> +struct ei_outer_stride_or_outer_size_impl +{ + static inline int value(const T& x) { return x.outerStride(); } +}; + +template +struct ei_outer_stride_or_outer_size_impl +{ + static inline int value(const T& x) { return x.outerSize(); } +}; + +template +inline int ei_outer_stride_or_outer_size(const T& x) +{ + return ei_outer_stride_or_outer_size_impl::value(x); +} + +template::type>::Flags)&DirectAccessBit> +struct ei_inner_stride_at_compile_time +{ + enum { ret = ei_traits::type>::InnerStrideAtCompileTime }; +}; + +template +struct ei_inner_stride_at_compile_time +{ + enum { ret = 1 }; +}; + +template::type>::Flags)&DirectAccessBit> +struct ei_outer_stride_at_compile_time +{ + enum { ret = ei_traits::type>::OuterStrideAtCompileTime }; +}; + +template +struct ei_outer_stride_at_compile_time +{ + enum { ret = 1 }; +}; + +#endif // EIGEN_STRIDE_H