1namespace Eigen {
2  namespace internal {
3    template<typename ArgType>
4    struct evaluator<Circulant<ArgType> >
5      : evaluator_base<Circulant<ArgType> >
6    {
7      typedef Circulant<ArgType> XprType;
8      typedef typename nested_eval<ArgType, XprType::ColsAtCompileTime>::type ArgTypeNested;
9      typedef typename remove_all<ArgTypeNested>::type ArgTypeNestedCleaned;
10      typedef typename XprType::CoeffReturnType CoeffReturnType;
11
12      enum {
13        CoeffReadCost = evaluator<ArgTypeNestedCleaned>::CoeffReadCost,
14        Flags = Eigen::ColMajor
15      };
16
17      evaluator(const XprType& xpr)
18        : m_argImpl(xpr.m_arg), m_rows(xpr.rows())
19      { }
20
21      CoeffReturnType coeff(Index row, Index col) const
22      {
23        Index index = row - col;
24        if (index < 0) index += m_rows;
25        return m_argImpl.coeff(index);
26      }
27
28      evaluator<ArgTypeNestedCleaned> m_argImpl;
29      const Index m_rows;
30    };
31  }
32}
33