Line data Source code
1 : /**
2 : * Copyright (c) 2025 Huawei Technologies Co., Ltd.
3 : * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4 : * CANN Open Software License Agreement Version 2.0 (the "License").
5 : * Please refer to the License for details. You may not use this file except in compliance with the License.
6 : * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7 : * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8 : * See LICENSE in the root of the software repository for the full text of the License.
9 : */
10 :
11 : #ifndef HCCLV2_ENUM_FACTORY_H
12 : #define HCCLV2_ENUM_FACTORY_H
13 :
14 : #include <cstdint>
15 : #include <sstream>
16 : #include <string>
17 :
18 : namespace Hccl {
19 : namespace EnumNameDetail {
20 : struct NameView {
21 : const char* data;
22 : unsigned int size;
23 : };
24 :
25 946 : inline const char* SkipSpacesAndCommas(const char* cursor)
26 : {
27 2548 : while ((*cursor == ' ') || (*cursor == ',')) {
28 1602 : ++cursor;
29 : }
30 946 : return cursor;
31 : }
32 :
33 : // "SDMA = 0" -> name is "SDMA"; stop at space or '='.
34 946 : inline const char* FindEnumeratorNameEnd(const char* cursor)
35 : {
36 11157 : while ((*cursor != '\0') && (*cursor != ',') && (*cursor != ' ') && (*cursor != '=')) {
37 10211 : ++cursor;
38 : }
39 946 : return cursor;
40 : }
41 :
42 : // Skip the initializer ("= 0") up to the comma between enumerators.
43 946 : inline const char* SkipUntilComma(const char* cursor)
44 : {
45 978 : while ((*cursor != '\0') && (*cursor != ',')) {
46 32 : ++cursor;
47 : }
48 946 : return cursor;
49 : }
50 :
51 : // Split the stringized enumerator list on commas. Pointers stay in that literal.
52 145 : inline unsigned int ParseNames(const char* enumeratorList, NameView* enumNames, unsigned int maxEnumCount)
53 : {
54 145 : unsigned int curEnumCount = 0;
55 145 : const char* cursor = enumeratorList;
56 1091 : while (*cursor != '\0') {
57 946 : cursor = SkipSpacesAndCommas(cursor);
58 946 : if (*cursor == '\0') {
59 0 : break;
60 : }
61 :
62 946 : const char* nameBegin = cursor;
63 946 : const char* nameEnd = FindEnumeratorNameEnd(cursor);
64 946 : if ((nameBegin != nameEnd) && (curEnumCount < maxEnumCount)) {
65 946 : enumNames[curEnumCount].data = nameBegin;
66 946 : enumNames[curEnumCount].size = static_cast<unsigned int>(nameEnd - nameBegin);
67 946 : ++curEnumCount;
68 : }
69 :
70 946 : cursor = SkipUntilComma(nameEnd);
71 : }
72 145 : return curEnumCount;
73 : }
74 : } // namespace EnumNameDetail
75 : } // namespace Hccl
76 :
77 : #define MAKE_ENUM(enumClass, ...) \
78 : class enumClass { \
79 : public: \
80 : enum Value : uint8_t { __VA_ARGS__, __COUNT__, INVALID }; \
81 : \
82 : enumClass() {} \
83 : \
84 : constexpr enumClass(Value v) : value(v) {} \
85 : \
86 : constexpr operator Value() const { return value; } \
87 : \
88 : constexpr bool operator==(enumClass a) const { return value == a.value; } \
89 : \
90 : constexpr bool operator!=(enumClass a) const { return value != a.value; } \
91 : \
92 : constexpr bool operator<(enumClass a) const { return value < a.value; } \
93 : \
94 : constexpr bool operator==(Value v) const { return value == v; } \
95 : \
96 : constexpr bool operator!=(Value v) const { return value != v; } \
97 : \
98 : constexpr bool operator<(Value v) const { return value < v; } \
99 : \
100 : std::string Describe() const \
101 : { \
102 : /* POD table: first call parses #__VA_ARGS__; views point at the literal, no heap. */ \
103 : static ::Hccl::EnumNameDetail::NameView enumNames[__COUNT__]; \
104 : static const unsigned int enumCount \
105 : = ::Hccl::EnumNameDetail::ParseNames(#__VA_ARGS__, enumNames, static_cast<unsigned int>(__COUNT__)); \
106 : const unsigned int enumValue = static_cast<unsigned int>(value); \
107 : if (enumValue >= enumCount) { \
108 : return std::string(#enumClass) + "::Invalid"; \
109 : } \
110 : const ::Hccl::EnumNameDetail::NameView& enumName = enumNames[enumValue]; \
111 : return std::string(#enumClass) + "::" + std::string(enumName.data, enumName.size); \
112 : } \
113 : \
114 : friend std::ostream& operator<<(std::ostream& stream, const enumClass& v) { return stream << v.Describe(); } \
115 : \
116 : private: \
117 : Value value{INVALID}; \
118 : };
119 :
120 : namespace std {
121 : struct EnumClassHash {
122 : template <typename T>
123 933134 : std::size_t operator()(T t) const
124 : {
125 933134 : return static_cast<std::size_t>(t);
126 : }
127 : };
128 : } // namespace std
129 :
130 : #endif // HCCLV2_ENUM_FACTORY_H
|