/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
|*                                                                            *|
|* Interface Declarations                                                     *|
|*                                                                            *|
|* Automatically generated file, do not edit!                                 *|
|*                                                                            *|
\*===----------------------------------------------------------------------===*/

namespace mlir::memref {

/// An interface for operations that access (by loading from or
/// storing to, atomically modifying, or otherwise) memory located at an
/// index within a memref whose semantics don't depend on the indexing scheme.
/// 
/// That is, a direct access op is one where, if `%b[%j0, %j1, ..., %jL]`
/// points to the same memory as `%a[%i0, %i1, ... %iK]`, it would be
/// legal to replace `%a[%i0, ..., %iK]` with %b[%j0, ... %jL]`.
/// 
/// Operations may impose constraints on allowable reindexings.
/// Returning a non-empty result from `getAccessedShape()` imposes constraints
/// on the dimensions whose strides need to be preserved.
/// 
/// This interface is intended to enable transformations such as folding in
/// aliasing operations (like `memref.subview` or `memref.collapse_shape`) or
/// linearizing memrefs (making them 1-D) to be generic over in-tree and
/// out-of-tree operations.
class IndexedAccessOpInterface;

} // namespace mlir::memref
namespace mlir::memref {

/// This is an interface for operations that perform a copy of some number
/// of values from `%src[%srcIndices...]` to `%dst[%dstIndices...]`. The copy
/// does not necessarily target some linear sequence of elements (it may, for
/// example, be strided), and there may be implicit offsets added to the source
/// and/or destination indices (for example, `amdgpu.gather_to_lds` can validly
/// implement this interface even though the destination index gets a lane ID *
/// copy size term added to it implicitly).
/// 
/// The motivating examples for this interface are operations that perform
/// direct loads to workgroup memory on GPUs.
/// 
/// This allows patterns that reindex memrefs (like folding in subview operations)
/// to treat such operations as a class, just like `IndexedAccessOpInterface`.
/// 
/// Unlike `IndexedAccessOpInterface`, this interface assumes that the elements
/// being copied are contiguous in memory and that the producers of the
/// operation have ensured this. That is, if the source memref is a
/// `memref<8x3xf32, strided<[9, 1]>>`, it is presumed that a memcpy of
/// 4 floats starting at the indices `[%x, %y]` is intended to read into
/// the space between the length-three rows.
class IndexedMemCopyOpInterface;

} // namespace mlir::memref
namespace mlir::memref {

/// An interface for operations that access (by loading from or
/// storing to, atomically modifying, or otherwise) memory located at an
/// index within a memref whose semantics don't depend on the indexing scheme.
/// 
/// That is, a direct access op is one where, if `%b[%j0, %j1, ..., %jL]`
/// points to the same memory as `%a[%i0, %i1, ... %iK]`, it would be
/// legal to replace `%a[%i0, ..., %iK]` with %b[%j0, ... %jL]`.
/// 
/// Operations may impose constraints on allowable reindexings.
/// Returning a non-empty result from `getAccessedShape()` imposes constraints
/// on the dimensions whose strides need to be preserved.
/// 
/// This interface is intended to enable transformations such as folding in
/// aliasing operations (like `memref.subview` or `memref.collapse_shape`) or
/// linearizing memrefs (making them 1-D) to be generic over in-tree and
/// out-of-tree operations.
namespace detail {
struct IndexedAccessOpInterfaceInterfaceTraits {
  struct Concept {
    /// The methods defined by the interface.
    ::mlir::TypedValue<::mlir::MemRefType> (*getAccessedMemref)(const Concept *impl, ::mlir::Operation *);
    ::mlir::Operation::operand_range (*getIndices)(const Concept *impl, ::mlir::Operation *);
    ::llvm::SmallVector<int64_t> (*getAccessedShape)(const Concept *impl, ::mlir::Operation *);
    std::optional<llvm::SmallVector<mlir::Value>> (*updateMemrefAndIndices)(const Concept *impl, ::mlir::Operation *, ::mlir::RewriterBase&, ::mlir::Value, ::mlir::ValueRange);
    bool (*hasInboundsIndices)(const Concept *impl, ::mlir::Operation *);
  };
  template<typename ConcreteOp>
  class Model : public Concept {
  public:
    using Interface = ::mlir::memref::IndexedAccessOpInterface;
    Model() : Concept{getAccessedMemref, getIndices, getAccessedShape, updateMemrefAndIndices, hasInboundsIndices} {}

    static inline ::mlir::TypedValue<::mlir::MemRefType> getAccessedMemref(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
    static inline ::mlir::Operation::operand_range getIndices(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
    static inline ::llvm::SmallVector<int64_t> getAccessedShape(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
    static inline std::optional<llvm::SmallVector<mlir::Value>> updateMemrefAndIndices(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::RewriterBase& rewriter, ::mlir::Value newMemref, ::mlir::ValueRange newIndices);
    static inline bool hasInboundsIndices(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
  };
  template<typename ConcreteOp>
  class FallbackModel : public Concept {
  public:
    using Interface = ::mlir::memref::IndexedAccessOpInterface;
    FallbackModel() : Concept{getAccessedMemref, getIndices, getAccessedShape, updateMemrefAndIndices, hasInboundsIndices} {}

    static inline ::mlir::TypedValue<::mlir::MemRefType> getAccessedMemref(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
    static inline ::mlir::Operation::operand_range getIndices(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
    static inline ::llvm::SmallVector<int64_t> getAccessedShape(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
    static inline std::optional<llvm::SmallVector<mlir::Value>> updateMemrefAndIndices(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::RewriterBase& rewriter, ::mlir::Value newMemref, ::mlir::ValueRange newIndices);
    static inline bool hasInboundsIndices(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
  };
  template<typename ConcreteModel, typename ConcreteOp>
  class ExternalModel : public FallbackModel<ConcreteModel> {
  public:
    using ConcreteEntity = ConcreteOp;
    ::llvm::SmallVector<int64_t> getAccessedShape(::mlir::Operation *tablegen_opaque_val) const;
    bool hasInboundsIndices(::mlir::Operation *tablegen_opaque_val) const;
  };
};
template <typename ConcreteOp>
struct IndexedAccessOpInterfaceTrait;

} // namespace detail
class IndexedAccessOpInterface : public ::mlir::OpInterface<IndexedAccessOpInterface, detail::IndexedAccessOpInterfaceInterfaceTraits> {
public:
  using ::mlir::OpInterface<IndexedAccessOpInterface, detail::IndexedAccessOpInterfaceInterfaceTraits>::OpInterface;
  template <typename ConcreteOp>
  struct Trait : public detail::IndexedAccessOpInterfaceTrait<ConcreteOp> {};

  /// Return the accessed memref. If the operation is not accessing memory through
  /// a memref in its current form, return the null value.
  ::mlir::TypedValue<::mlir::MemRefType> getAccessedMemref();

  /// Return the indices that are used to access the memref returned by `getAccessedMemref()`.
  /// 
  /// The size of this range must be equal to the rank of the memref returned by
  /// `getAccessedMemref()`.
  ::mlir::Operation::operand_range getIndices();

  /// Return the shape of the portion of the memref that is being accessed by
  /// this operation, if known. This shape describes the access dimensions
  /// whose strides are semantically important for this operation.
  /// Implementations shall omit dimensions whose strides do not affect the
  /// operation semantics. (In particular, if an operation will access one
  /// element of the base memref, this method should return `{}`.)
  /// 
  /// Reindexing transformations may not modify the *strides* of the trailing
  /// N dimensions, where N is the size returned value, and should ensure that
  /// at least N indexing dimensions remain after the transformation.
  ::llvm::SmallVector<int64_t> getAccessedShape();

  /// Updates the memref being accessed to `newMemref` and the indices to
  /// `newIndices`. If `std::nullopt` is returned, the operation was
  /// updated in-place (the common case), while if a vector of values
  /// is returned, they should be used to replace the operation being
  /// updated.
  /// 
  /// This implementation of this method shall use the `modifyOpInPlace` method
  /// on the provided rewriter when applicable. It may also create or clone operations.
  /// However, the operation must not replace itself, and should instead return
  /// a vector of replacement results to the caller. (This allows for post-processing
  /// and prevents stale references.)
  /// 
  /// The caller must ensure that the new memref/index pair points to the same
  /// location in memory as the existing arguments.
  /// 
  /// The element types of the memref may not change.
  std::optional<llvm::SmallVector<mlir::Value>> updateMemrefAndIndices(::mlir::RewriterBase& rewriter, ::mlir::Value newMemref, ::mlir::ValueRange newIndices);

  /// Return true if, either by definition or due to some attribute,
  /// it's known that all indices are non-negative and less than the size
  /// of the dimension they index.
  bool hasInboundsIndices();
};

} // namespace mlir::memref
namespace mlir::memref {

/// This is an interface for operations that perform a copy of some number
/// of values from `%src[%srcIndices...]` to `%dst[%dstIndices...]`. The copy
/// does not necessarily target some linear sequence of elements (it may, for
/// example, be strided), and there may be implicit offsets added to the source
/// and/or destination indices (for example, `amdgpu.gather_to_lds` can validly
/// implement this interface even though the destination index gets a lane ID *
/// copy size term added to it implicitly).
/// 
/// The motivating examples for this interface are operations that perform
/// direct loads to workgroup memory on GPUs.
/// 
/// This allows patterns that reindex memrefs (like folding in subview operations)
/// to treat such operations as a class, just like `IndexedAccessOpInterface`.
/// 
/// Unlike `IndexedAccessOpInterface`, this interface assumes that the elements
/// being copied are contiguous in memory and that the producers of the
/// operation have ensured this. That is, if the source memref is a
/// `memref<8x3xf32, strided<[9, 1]>>`, it is presumed that a memcpy of
/// 4 floats starting at the indices `[%x, %y]` is intended to read into
/// the space between the length-three rows.
namespace detail {
struct IndexedMemCopyOpInterfaceInterfaceTraits {
  struct Concept {
    /// The methods defined by the interface.
    ::mlir::TypedValue<::mlir::MemRefType> (*getSrc)(const Concept *impl, ::mlir::Operation *);
    ::mlir::Operation::operand_range (*getSrcIndices)(const Concept *impl, ::mlir::Operation *);
    ::mlir::TypedValue<::mlir::MemRefType> (*getDst)(const Concept *impl, ::mlir::Operation *);
    ::mlir::Operation::operand_range (*getDstIndices)(const Concept *impl, ::mlir::Operation *);
    void (*setMemrefsAndIndices)(const Concept *impl, ::mlir::Operation *, ::mlir::RewriterBase&, ::mlir::Value, ::mlir::ValueRange, ::mlir::Value, ::mlir::ValueRange);
    bool (*hasInboundsSrcIndices)(const Concept *impl, ::mlir::Operation *);
    bool (*hasInboundsDstIndices)(const Concept *impl, ::mlir::Operation *);
  };
  template<typename ConcreteOp>
  class Model : public Concept {
  public:
    using Interface = ::mlir::memref::IndexedMemCopyOpInterface;
    Model() : Concept{getSrc, getSrcIndices, getDst, getDstIndices, setMemrefsAndIndices, hasInboundsSrcIndices, hasInboundsDstIndices} {}

    static inline ::mlir::TypedValue<::mlir::MemRefType> getSrc(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
    static inline ::mlir::Operation::operand_range getSrcIndices(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
    static inline ::mlir::TypedValue<::mlir::MemRefType> getDst(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
    static inline ::mlir::Operation::operand_range getDstIndices(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
    static inline void setMemrefsAndIndices(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::RewriterBase& rewriter, ::mlir::Value newSrc, ::mlir::ValueRange newSrcIndices, ::mlir::Value newDst, ::mlir::ValueRange newDstIndices);
    static inline bool hasInboundsSrcIndices(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
    static inline bool hasInboundsDstIndices(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
  };
  template<typename ConcreteOp>
  class FallbackModel : public Concept {
  public:
    using Interface = ::mlir::memref::IndexedMemCopyOpInterface;
    FallbackModel() : Concept{getSrc, getSrcIndices, getDst, getDstIndices, setMemrefsAndIndices, hasInboundsSrcIndices, hasInboundsDstIndices} {}

    static inline ::mlir::TypedValue<::mlir::MemRefType> getSrc(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
    static inline ::mlir::Operation::operand_range getSrcIndices(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
    static inline ::mlir::TypedValue<::mlir::MemRefType> getDst(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
    static inline ::mlir::Operation::operand_range getDstIndices(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
    static inline void setMemrefsAndIndices(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::RewriterBase& rewriter, ::mlir::Value newSrc, ::mlir::ValueRange newSrcIndices, ::mlir::Value newDst, ::mlir::ValueRange newDstIndices);
    static inline bool hasInboundsSrcIndices(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
    static inline bool hasInboundsDstIndices(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
  };
  template<typename ConcreteModel, typename ConcreteOp>
  class ExternalModel : public FallbackModel<ConcreteModel> {
  public:
    using ConcreteEntity = ConcreteOp;
    bool hasInboundsSrcIndices(::mlir::Operation *tablegen_opaque_val) const;
    bool hasInboundsDstIndices(::mlir::Operation *tablegen_opaque_val) const;
  };
};
template <typename ConcreteOp>
struct IndexedMemCopyOpInterfaceTrait;

} // namespace detail
class IndexedMemCopyOpInterface : public ::mlir::OpInterface<IndexedMemCopyOpInterface, detail::IndexedMemCopyOpInterfaceInterfaceTraits> {
public:
  using ::mlir::OpInterface<IndexedMemCopyOpInterface, detail::IndexedMemCopyOpInterfaceInterfaceTraits>::OpInterface;
  template <typename ConcreteOp>
  struct Trait : public detail::IndexedMemCopyOpInterfaceTrait<ConcreteOp> {};

  /// Return the source memref for this copy operation. If the operation is not
  /// currently copying from a memref source, return the null value.
  ::mlir::TypedValue<::mlir::MemRefType> getSrc();

  /// Return the indices that are used to access the source memref.
  /// 
  /// The size of this range must be equal to the rank of the memref returned by
  /// `getSrc()`.
  ::mlir::Operation::operand_range getSrcIndices();

  /// Return the destination memref for this copy operation. If the operation is
  /// not currently copying to a memref destination, return the null value.
  ::mlir::TypedValue<::mlir::MemRefType> getDst();

  /// Return the indices that are used to access the destination memref.
  /// 
  /// The size of this range must be equal to the rank of the memref returned by
  /// `getDst()`.
  ::mlir::Operation::operand_range getDstIndices();

  /// Update the operation with `newSrcMemref` as the new source memref,
  /// `newSrcIndices` as the new source indices, `newDst` as the new destination
  /// memref, and `newDstIndices` as the new destination indices, leaving
  /// other properties unchanged.
  /// 
  /// Note that, unlike the method on indexed accessors, this method doesn't
  /// currently allow for the possibility of cloning since DMA ops generally
  /// do not return results. If needed, such suppport could be added in
  /// the future.
  /// 
  /// The implementation is responsible for issuing rewriter notifications
  /// via modifyOpInPlace().
  /// 
  /// The caller must ensure that the new memref/index pairs point to the same
  /// location in memory.
  void setMemrefsAndIndices(::mlir::RewriterBase& rewriter, ::mlir::Value newSrc, ::mlir::ValueRange newSrcIndices, ::mlir::Value newDst, ::mlir::ValueRange newDstIndices);

  /// Return true if, either by definition or due to some attribute, it's
  /// known that the source indices are non-negative and less than the size of
  /// the dimension they index.
  bool hasInboundsSrcIndices();

  /// Return true if, either by definition or due to some attribute, it's
  /// known that the destination indices are non-negative and less than the
  /// size of the dimension they index.
  bool hasInboundsDstIndices();
};

} // namespace mlir::memref
namespace mlir::memref::detail {

  template <typename ConcreteOp>
  struct IndexedAccessOpInterfaceTrait : public ::mlir::OpInterface<IndexedAccessOpInterface, detail::IndexedAccessOpInterfaceInterfaceTraits>::Trait<ConcreteOp> {

    /// Return the shape of the portion of the memref that is being accessed by
    /// this operation, if known. This shape describes the access dimensions
    /// whose strides are semantically important for this operation.
    /// Implementations shall omit dimensions whose strides do not affect the
    /// operation semantics. (In particular, if an operation will access one
    /// element of the base memref, this method should return `{}`.)
    /// 
    /// Reindexing transformations may not modify the *strides* of the trailing
    /// N dimensions, where N is the size returned value, and should ensure that
    /// at least N indexing dimensions remain after the transformation.
    ::llvm::SmallVector<int64_t> getAccessedShape() {
      return ::llvm::SmallVector<int64_t>{};
    }

    /// Return true if, either by definition or due to some attribute,
    /// it's known that all indices are non-negative and less than the size
    /// of the dimension they index.
    bool hasInboundsIndices() {
      return true;
    }
    static ::llvm::LogicalResult verifyTrait(::mlir::Operation *op) {
      return ::mlir::memref::detail::verifyIndexedAccessOpInterface(op);
    }
  };

} // namespace mlir::memref::detail
namespace mlir::memref::detail {

  template <typename ConcreteOp>
  struct IndexedMemCopyOpInterfaceTrait : public ::mlir::OpInterface<IndexedMemCopyOpInterface, detail::IndexedMemCopyOpInterfaceInterfaceTraits>::Trait<ConcreteOp> {

    /// Return true if, either by definition or due to some attribute, it's
    /// known that the source indices are non-negative and less than the size of
    /// the dimension they index.
    bool hasInboundsSrcIndices() {
      return true;
    }

    /// Return true if, either by definition or due to some attribute, it's
    /// known that the destination indices are non-negative and less than the
    /// size of the dimension they index.
    bool hasInboundsDstIndices() {
      return true;
    }
    static ::llvm::LogicalResult verifyTrait(::mlir::Operation *op) {
      return ::mlir::memref::detail::verifyIndexedMemCopyOpInterface(op);
    }
  };

} // namespace mlir::memref::detail
namespace mlir::memref {

template<typename ConcreteOp>
::mlir::TypedValue<::mlir::MemRefType> detail::IndexedAccessOpInterfaceInterfaceTraits::Model<ConcreteOp>::getAccessedMemref(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
  return (llvm::cast<ConcreteOp>(tablegen_opaque_val)).getAccessedMemref();
}
template<typename ConcreteOp>
::mlir::Operation::operand_range detail::IndexedAccessOpInterfaceInterfaceTraits::Model<ConcreteOp>::getIndices(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
  return (llvm::cast<ConcreteOp>(tablegen_opaque_val)).getIndices();
}
template<typename ConcreteOp>
::llvm::SmallVector<int64_t> detail::IndexedAccessOpInterfaceInterfaceTraits::Model<ConcreteOp>::getAccessedShape(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
  return (llvm::cast<ConcreteOp>(tablegen_opaque_val)).getAccessedShape();
}
template<typename ConcreteOp>
std::optional<llvm::SmallVector<mlir::Value>> detail::IndexedAccessOpInterfaceInterfaceTraits::Model<ConcreteOp>::updateMemrefAndIndices(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::RewriterBase& rewriter, ::mlir::Value newMemref, ::mlir::ValueRange newIndices) {
  return (llvm::cast<ConcreteOp>(tablegen_opaque_val)).updateMemrefAndIndices(rewriter, newMemref, newIndices);
}
template<typename ConcreteOp>
bool detail::IndexedAccessOpInterfaceInterfaceTraits::Model<ConcreteOp>::hasInboundsIndices(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
  return (llvm::cast<ConcreteOp>(tablegen_opaque_val)).hasInboundsIndices();
}
template<typename ConcreteOp>
::mlir::TypedValue<::mlir::MemRefType> detail::IndexedAccessOpInterfaceInterfaceTraits::FallbackModel<ConcreteOp>::getAccessedMemref(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
  return static_cast<const ConcreteOp *>(impl)->getAccessedMemref(tablegen_opaque_val);
}
template<typename ConcreteOp>
::mlir::Operation::operand_range detail::IndexedAccessOpInterfaceInterfaceTraits::FallbackModel<ConcreteOp>::getIndices(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
  return static_cast<const ConcreteOp *>(impl)->getIndices(tablegen_opaque_val);
}
template<typename ConcreteOp>
::llvm::SmallVector<int64_t> detail::IndexedAccessOpInterfaceInterfaceTraits::FallbackModel<ConcreteOp>::getAccessedShape(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
  return static_cast<const ConcreteOp *>(impl)->getAccessedShape(tablegen_opaque_val);
}
template<typename ConcreteOp>
std::optional<llvm::SmallVector<mlir::Value>> detail::IndexedAccessOpInterfaceInterfaceTraits::FallbackModel<ConcreteOp>::updateMemrefAndIndices(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::RewriterBase& rewriter, ::mlir::Value newMemref, ::mlir::ValueRange newIndices) {
  return static_cast<const ConcreteOp *>(impl)->updateMemrefAndIndices(tablegen_opaque_val, rewriter, newMemref, newIndices);
}
template<typename ConcreteOp>
bool detail::IndexedAccessOpInterfaceInterfaceTraits::FallbackModel<ConcreteOp>::hasInboundsIndices(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
  return static_cast<const ConcreteOp *>(impl)->hasInboundsIndices(tablegen_opaque_val);
}
template<typename ConcreteModel, typename ConcreteOp>
::llvm::SmallVector<int64_t> detail::IndexedAccessOpInterfaceInterfaceTraits::ExternalModel<ConcreteModel, ConcreteOp>::getAccessedShape(::mlir::Operation *tablegen_opaque_val) const {
return ::llvm::SmallVector<int64_t>{};
}
template<typename ConcreteModel, typename ConcreteOp>
bool detail::IndexedAccessOpInterfaceInterfaceTraits::ExternalModel<ConcreteModel, ConcreteOp>::hasInboundsIndices(::mlir::Operation *tablegen_opaque_val) const {
return true;
}

} // namespace mlir::memref
namespace mlir::memref {

template<typename ConcreteOp>
::mlir::TypedValue<::mlir::MemRefType> detail::IndexedMemCopyOpInterfaceInterfaceTraits::Model<ConcreteOp>::getSrc(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
  return (llvm::cast<ConcreteOp>(tablegen_opaque_val)).getSrc();
}
template<typename ConcreteOp>
::mlir::Operation::operand_range detail::IndexedMemCopyOpInterfaceInterfaceTraits::Model<ConcreteOp>::getSrcIndices(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
  return (llvm::cast<ConcreteOp>(tablegen_opaque_val)).getSrcIndices();
}
template<typename ConcreteOp>
::mlir::TypedValue<::mlir::MemRefType> detail::IndexedMemCopyOpInterfaceInterfaceTraits::Model<ConcreteOp>::getDst(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
  return (llvm::cast<ConcreteOp>(tablegen_opaque_val)).getDst();
}
template<typename ConcreteOp>
::mlir::Operation::operand_range detail::IndexedMemCopyOpInterfaceInterfaceTraits::Model<ConcreteOp>::getDstIndices(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
  return (llvm::cast<ConcreteOp>(tablegen_opaque_val)).getDstIndices();
}
template<typename ConcreteOp>
void detail::IndexedMemCopyOpInterfaceInterfaceTraits::Model<ConcreteOp>::setMemrefsAndIndices(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::RewriterBase& rewriter, ::mlir::Value newSrc, ::mlir::ValueRange newSrcIndices, ::mlir::Value newDst, ::mlir::ValueRange newDstIndices) {
  return (llvm::cast<ConcreteOp>(tablegen_opaque_val)).setMemrefsAndIndices(rewriter, newSrc, newSrcIndices, newDst, newDstIndices);
}
template<typename ConcreteOp>
bool detail::IndexedMemCopyOpInterfaceInterfaceTraits::Model<ConcreteOp>::hasInboundsSrcIndices(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
  return (llvm::cast<ConcreteOp>(tablegen_opaque_val)).hasInboundsSrcIndices();
}
template<typename ConcreteOp>
bool detail::IndexedMemCopyOpInterfaceInterfaceTraits::Model<ConcreteOp>::hasInboundsDstIndices(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
  return (llvm::cast<ConcreteOp>(tablegen_opaque_val)).hasInboundsDstIndices();
}
template<typename ConcreteOp>
::mlir::TypedValue<::mlir::MemRefType> detail::IndexedMemCopyOpInterfaceInterfaceTraits::FallbackModel<ConcreteOp>::getSrc(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
  return static_cast<const ConcreteOp *>(impl)->getSrc(tablegen_opaque_val);
}
template<typename ConcreteOp>
::mlir::Operation::operand_range detail::IndexedMemCopyOpInterfaceInterfaceTraits::FallbackModel<ConcreteOp>::getSrcIndices(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
  return static_cast<const ConcreteOp *>(impl)->getSrcIndices(tablegen_opaque_val);
}
template<typename ConcreteOp>
::mlir::TypedValue<::mlir::MemRefType> detail::IndexedMemCopyOpInterfaceInterfaceTraits::FallbackModel<ConcreteOp>::getDst(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
  return static_cast<const ConcreteOp *>(impl)->getDst(tablegen_opaque_val);
}
template<typename ConcreteOp>
::mlir::Operation::operand_range detail::IndexedMemCopyOpInterfaceInterfaceTraits::FallbackModel<ConcreteOp>::getDstIndices(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
  return static_cast<const ConcreteOp *>(impl)->getDstIndices(tablegen_opaque_val);
}
template<typename ConcreteOp>
void detail::IndexedMemCopyOpInterfaceInterfaceTraits::FallbackModel<ConcreteOp>::setMemrefsAndIndices(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::RewriterBase& rewriter, ::mlir::Value newSrc, ::mlir::ValueRange newSrcIndices, ::mlir::Value newDst, ::mlir::ValueRange newDstIndices) {
  return static_cast<const ConcreteOp *>(impl)->setMemrefsAndIndices(tablegen_opaque_val, rewriter, newSrc, newSrcIndices, newDst, newDstIndices);
}
template<typename ConcreteOp>
bool detail::IndexedMemCopyOpInterfaceInterfaceTraits::FallbackModel<ConcreteOp>::hasInboundsSrcIndices(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
  return static_cast<const ConcreteOp *>(impl)->hasInboundsSrcIndices(tablegen_opaque_val);
}
template<typename ConcreteOp>
bool detail::IndexedMemCopyOpInterfaceInterfaceTraits::FallbackModel<ConcreteOp>::hasInboundsDstIndices(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
  return static_cast<const ConcreteOp *>(impl)->hasInboundsDstIndices(tablegen_opaque_val);
}
template<typename ConcreteModel, typename ConcreteOp>
bool detail::IndexedMemCopyOpInterfaceInterfaceTraits::ExternalModel<ConcreteModel, ConcreteOp>::hasInboundsSrcIndices(::mlir::Operation *tablegen_opaque_val) const {
return true;
}
template<typename ConcreteModel, typename ConcreteOp>
bool detail::IndexedMemCopyOpInterfaceInterfaceTraits::ExternalModel<ConcreteModel, ConcreteOp>::hasInboundsDstIndices(::mlir::Operation *tablegen_opaque_val) const {
return true;
}

} // namespace mlir::memref
