chromium/third_party/eigen3/src/Eigen/src/Core/Product.h

// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008-2011 Gael Guennebaud <[email protected]>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

#ifndef EIGEN_PRODUCT_H
#define EIGEN_PRODUCT_H

// IWYU pragma: private
#include "./InternalHeaderCheck.h"

namespace Eigen {

template <typename Lhs, typename Rhs, int Option, typename StorageKind>
class ProductImpl;

namespace internal {

traits<Product<Lhs, Rhs, Option>>;

struct TransposeProductEnum {};
template <typename Xpr>
struct TransposeKind {};

template <typename Lhs, typename Rhs>
struct TransposeProductKind {};

template <typename Lhs, typename Rhs, int Option, int Kind = TransposeProductKind<Lhs, Rhs>::Kind>
struct product_transpose_helper {};

product_transpose_helper<Lhs, Rhs, Option, TransposeProductEnum::MatrixMatrix>;
product_transpose_helper<Lhs, Rhs, Option, TransposeProductEnum::PermutationMatrix>;
product_transpose_helper<Lhs, Rhs, Option, TransposeProductEnum::MatrixPermutation>;

}  // end namespace internal

/** \class Product
 * \ingroup Core_Module
 *
 * \brief Expression of the product of two arbitrary matrices or vectors
 *
 * \tparam Lhs_ the type of the left-hand side expression
 * \tparam Rhs_ the type of the right-hand side expression
 *
 * This class represents an expression of the product of two arbitrary matrices.
 *
 * The other template parameters are:
 * \tparam Option     can be DefaultProduct, AliasFreeProduct, or LazyProduct
 *
 */
template <typename Lhs_, typename Rhs_, int Option>
class Product
    : public ProductImpl<Lhs_, Rhs_, Option,
                         typename internal::product_promote_storage_type<
                             typename internal::traits<Lhs_>::StorageKind, typename internal::traits<Rhs_>::StorageKind,
                             internal::product_type<Lhs_, Rhs_>::ret>::ret> {};

namespace internal {

template <typename Lhs, typename Rhs, int Option, int ProductTag = internal::product_type<Lhs, Rhs>::ret>
class dense_product_base : public internal::dense_xpr_base<Product<Lhs, Rhs, Option>>::type {};

/** Conversion to scalar for inner-products */
dense_product_base<Lhs, Rhs, Option, InnerProduct>;

}  // namespace internal

// Generic API dispatcher
template <typename Lhs, typename Rhs, int Option, typename StorageKind>
class ProductImpl : public internal::generic_xpr_base<Product<Lhs, Rhs, Option>, MatrixXpr, StorageKind>::type {};

ProductImpl<Lhs, Rhs, Option, Dense>;

}  // end namespace Eigen

#endif  // EIGEN_PRODUCT_H