xref: /llvm-project/mlir/lib/Dialect/SparseTensor/IR/Detail/TemplateExtras.h (revision 7c2ef38c36eda2907cd6a3efff88bb86a1b381a3)
1 //===- TemplateExtras.h -----------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef MLIR_DIALECT_SPARSETENSOR_IR_DETAIL_TEMPLATEEXTRAS_H
10 #define MLIR_DIALECT_SPARSETENSOR_IR_DETAIL_TEMPLATEEXTRAS_H
11 
12 #include <utility>
13 
14 #include "llvm/ADT/STLExtras.h"
15 #include "llvm/Support/raw_ostream.h"
16 
17 namespace mlir {
18 namespace sparse_tensor {
19 namespace ir_detail {
20 
21 //===----------------------------------------------------------------------===//
22 template <typename T>
23 using has_print_method =
24     decltype(std::declval<T>().print(std::declval<llvm::raw_ostream &>()));
25 template <typename T>
26 using detect_has_print_method = llvm::is_detected<has_print_method, T>;
27 template <typename T, typename R = void>
28 using enable_if_has_print_method =
29     std::enable_if_t<detect_has_print_method<T>::value, R>;
30 
31 /// Generic template for defining `operator<<` overloads which delegate
32 /// to `T::print(raw_ostream&) const`.
33 template <typename T>
34 inline enable_if_has_print_method<T, llvm::raw_ostream &>
35 operator<<(llvm::raw_ostream &os, T const &t) {
36   t.print(os);
37   return os;
38 }
39 
40 //===----------------------------------------------------------------------===//
41 template <typename T>
42 static constexpr bool IsZeroCostAbstraction =
43     // These two predicates license the compiler to make optimizations.
44     std::is_trivially_copyable_v<T> && std::is_trivially_destructible_v<T> &&
45     // This helps ensure ABI compatibility (e.g., padding and alignment).
46     std::is_standard_layout_v<T> &&
47     // These two are what SmallVector uses to determine whether it can
48     // use memcpy.
49     std::is_trivially_copy_constructible<T>::value &&
50     std::is_trivially_move_constructible<T>::value;
51 
52 //===----------------------------------------------------------------------===//
53 
54 } // namespace ir_detail
55 } // namespace sparse_tensor
56 } // namespace mlir
57 
58 #endif // MLIR_DIALECT_SPARSETENSOR_IR_DETAIL_TEMPLATEEXTRAS_H
59