scc 2025.09
SystemC components library
cci_util.h
1/*******************************************************************************
2 * Copyright 2024 MINRES Technologies GmbH
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *******************************************************************************/
16
17#ifndef _SYSC_SCC_CCI_UTIL_H_
18#define _SYSC_SCC_CCI_UTIL_H_
19
20#include <boost/preprocessor.hpp>
21#include <cci_configuration>
22
23#define DEFINE_ENUM_DECL_VAL(r, name, val) val // BOOST_PP_CAT(name, BOOST_PP_CAT(_, val))
24#define DEFINE_ENUM_VAL_STR(r, name, val) BOOST_PP_STRINGIZE(val)
25#define ASSIGN_ENUM_MAP_ENTRY(r, name, val) lut[#val] = name::val;
26#define CONCAT_OP(s, state, x) state x
27#define CONCAT(SEQ) BOOST_PP_SEQ_FOLD_LEFT(CONCAT_OP, BOOST_PP_SEQ_HEAD(SEQ), BOOST_PP_SEQ_TAIL(SEQ)) // expands to boost
28
40#if CCI_VERSION_MAJOR == 1 && CCI_VERSION_MINOR == 0 && CCI_VERSION_PATCH == 0
41#define DEFINE_ENUM4CCI(name, val_seq) \
42 enum class name { BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_TRANSFORM(DEFINE_ENUM_DECL_VAL, name, val_seq)) }; \
43 namespace cci { \
44 namespace { \
45 std::unordered_map<std::string, name> name##_lut_init() { \
46 std::unordered_map<std::string, name> lut; \
47 CONCAT(BOOST_PP_SEQ_TRANSFORM(ASSIGN_ENUM_MAP_ENTRY, name, val_seq)) \
48 return lut; \
49 } \
50 } \
51 template <> inline bool cci_value_converter<name>::pack(cci_value::reference dst, name const& src) { \
52 static const char* str_val[] = {BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_TRANSFORM(DEFINE_ENUM_VAL_STR, name, val_seq))}; \
53 dst.set_string(str_val[static_cast<unsigned>(src)]); \
54 return true; \
55 } \
56 template <> inline bool cci_value_converter<name>::unpack(name& dst, cci::cci_value::const_reference src) { \
57 static const std::unordered_map<std::string, name> lut = name##_lut_init(); \
58 if(!src.is_string()) \
59 return false; \
60 auto it = lut.find(src.get_string()); \
61 if(it != std::end(lut)) { \
62 dst = it->second; \
63 return true; \
64 } \
65 return false; \
66 } \
67 }
68
69#define DEFINE_NS_ENUM4CCI(ns_name, name, val_seq) \
70 namespace ns_name { \
71 enum class name { BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_TRANSFORM(DEFINE_ENUM_DECL_VAL, name, val_seq)) }; \
72 } \
73 namespace cci { \
74 namespace { \
75 std::unordered_map<std::string, ns_name::name> ns_name##_##name##_lut_init() { \
76 std::unordered_map<std::string, ns_name::name> lut; \
77 CONCAT(BOOST_PP_SEQ_TRANSFORM(ASSIGN_ENUM_MAP_ENTRY, ns_name::name, val_seq)) \
78 return lut; \
79 } \
80 } \
81 template <> inline bool cci_value_converter<ns_name::name>::pack(cci_value::reference dst, ns_name::name const& src) { \
82 static const char* str_val[] = {BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_TRANSFORM(DEFINE_ENUM_VAL_STR, name, val_seq))}; \
83 dst.set_string(str_val[static_cast<unsigned>(src)]); \
84 return true; \
85 } \
86 template <> inline bool cci_value_converter<ns_name::name>::unpack(ns_name::name& dst, cci::cci_value::const_reference src) { \
87 static const std::unordered_map<std::string, ns_name::name> lut = ns_name##_##name##_lut_init(); \
88 if(!src.is_string()) \
89 return false; \
90 auto it = lut.find(src.get_string()); \
91 if(it != std::end(lut)) { \
92 dst = it->second; \
93 return true; \
94 } \
95 return false; \
96 } \
97 }
98#else
99#define DEFINE_ENUM4CCI(name, val_seq) \
100 enum class name { BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_TRANSFORM(DEFINE_ENUM_DECL_VAL, name, val_seq)) }; \
101 namespace cci { \
102 namespace { \
103 std::unordered_map<std::string, name> name##_lut_init() { \
104 std::unordered_map<std::string, name> lut; \
105 CONCAT(BOOST_PP_SEQ_TRANSFORM(ASSIGN_ENUM_MAP_ENTRY, name, val_seq)) \
106 return lut; \
107 } \
108 } \
109 template <> struct cci_value_converter<name> { \
110 static inline bool pack(cci_value::reference dst, name const& src) { \
111 static const char* str_val[] = {BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_TRANSFORM(DEFINE_ENUM_VAL_STR, name, val_seq))}; \
112 dst.set_string(str_val[static_cast<unsigned>(src)]); \
113 return true; \
114 } \
115 static inline bool unpack(name& dst, cci::cci_value::const_reference src) { \
116 static const std::unordered_map<std::string, name> lut = name##_lut_init(); \
117 if(!src.is_string()) \
118 return false; \
119 auto it = lut.find(src.get_string()); \
120 if(it != std::end(lut)) { \
121 dst = it->second; \
122 return true; \
123 } \
124 return false; \
125 } \
126 }; \
127 }
128
129#define DEFINE_NS_ENUM4CCI(ns_name, name, val_seq) \
130 namespace ns_name { \
131 enum class name { BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_TRANSFORM(DEFINE_ENUM_DECL_VAL, name, val_seq)) }; \
132 } \
133 namespace cci { \
134 namespace { \
135 std::unordered_map<std::string, ns_name::name> ns_name##_##name##_lut_init() { \
136 std::unordered_map<std::string, ns_name::name> lut; \
137 CONCAT(BOOST_PP_SEQ_TRANSFORM(ASSIGN_ENUM_MAP_ENTRY, ns_name::name, val_seq)) \
138 return lut; \
139 } \
140 } \
141 template <> struct cci_value_converter<ns_name ::name> { \
142 static inline bool pack(cci_value::reference dst, ns_name::name const& src) { \
143 static const char* str_val[] = {BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_TRANSFORM(DEFINE_ENUM_VAL_STR, name, val_seq))}; \
144 dst.set_string(str_val[static_cast<unsigned>(src)]); \
145 return true; \
146 } \
147 static inline bool unpack(ns_name::name& dst, cci::cci_value::const_reference src) { \
148 static const std::unordered_map<std::string, ns_name::name> lut = ns_name##_##name##_lut_init(); \
149 if(!src.is_string()) \
150 return false; \
151 auto it = lut.find(src.get_string()); \
152 if(it != std::end(lut)) { \
153 dst = it->second; \
154 return true; \
155 } \
156 return false; \
157 } \
158 }; \
159 }
160#endif
161#endif /* _SYSC_SCC_CCI_UTIL_H_ */