1#pragma once
2
3#include <c10/macros/Macros.h>
4#include <c10/util/Exception.h>
5#include <c10/util/Optional.h>
6#include <c10/util/string_view.h>
7#include <string>
8#include <utility>
9#include <ostream>
10
11namespace c10 {
12
13// TODO: consider storing namespace separately too
14struct OperatorName final {
15 std::string name;
16 std::string overload_name;
17 OperatorName(std::string name, std::string overload_name)
18 : name(std::move(name)), overload_name(std::move(overload_name)) {}
19
20 // TODO: These two functions below are slow! Fix internal data structures so
21 // I don't have to manually reconstruct the namespaces!
22
23 // Return the namespace of this OperatorName, if it exists. The
24 // returned string_view is only live as long as the OperatorName
25 // exists and name is not mutated
26 c10::optional<c10::string_view> getNamespace() const {
27 auto pos = name.find("::");
28 if (pos == std::string::npos) {
29 return c10::nullopt;
30 } else {
31 return c10::make_optional(c10::string_view(name.data(), pos));
32 }
33 }
34
35 // Returns true if we successfully set the namespace
36 bool setNamespaceIfNotSet(const char* ns) {
37 if (!getNamespace().has_value()) {
38 const auto ns_len = strlen(ns);
39 const auto old_name_size = name.size();
40 name.resize(ns_len + 2 + old_name_size);
41 // Shift current value of name to the end of the new space.
42 name.replace(name.size() - old_name_size, old_name_size, name, 0, old_name_size);
43 name.replace(0, ns_len, ns, ns_len);
44 name[ns_len] = ':';
45 name[ns_len + 1] = ':';
46 return true;
47 } else {
48 return false;
49 }
50 }
51};
52
53// Non-owning view of an OperatorName. Unlike OperatorName, most of
54// its functions are constexpr, so it can be used for compile time
55// computations
56struct OperatorNameView final {
57 c10::string_view name;
58 c10::string_view overload_name;
59 constexpr OperatorNameView(c10::string_view name, c10::string_view overload_name)
60 : name(name), overload_name(overload_name) {}
61 // Parses strings like "foo.overload" and also "foo"
62 constexpr static OperatorNameView parse(c10::string_view full_name) {
63 auto i = full_name.find('.');
64 if (i == c10::string_view::npos) {
65 return OperatorNameView(full_name, c10::string_view());
66 } else {
67 return OperatorNameView(full_name.substr(0, i), full_name.substr(i + 1));
68 }
69 }
70};
71
72inline bool operator==(const OperatorName& lhs, const OperatorName& rhs) {
73 return lhs.name == rhs.name && lhs.overload_name == rhs.overload_name;
74}
75
76inline bool operator!=(const OperatorName& lhs, const OperatorName& rhs) {
77 return !operator==(lhs, rhs);
78}
79
80TORCH_API std::string toString(const OperatorName& opName);
81TORCH_API std::ostream& operator<<(std::ostream&, const OperatorName&);
82
83} // namespace c10
84
85namespace std {
86 template <>
87 struct hash<::c10::OperatorName> {
88 size_t operator()(const ::c10::OperatorName& x) const {
89 return std::hash<std::string>()(x.name) ^ (~ std::hash<std::string>()(x.overload_name));
90 }
91 };
92}
93