16#ifndef SIMICS_ATTRIBUTE_TRAITS_H
17#define SIMICS_ATTRIBUTE_TRAITS_H
19#include <simics/base/attr-value.h>
41 if (size > (std::numeric_limits<unsigned>::max)()) {
43 "Size exceeds maximum supported size for a Simics attribute"
52 static_assert(!std::is_same<T, T>::value,
53 "Specialization of attr_to_std<T> & std_to_attr<T> for "
54 "type T is required.");
55 static attr_value_t
f(
const T &src);
60 static_assert(!std::is_same<T, T>::value,
61 "Specialization of attr_to_std<T> & std_to_attr<T> for "
62 "type T is required.");
63 static T
f(
const attr_value_t &src);
72 return SIM_make_attr_object(src);
74 attr_value_t ret = SIM_alloc_attr_list(2);
75 SIM_attr_list_set_item(&ret, 0, SIM_make_attr_object(src));
76 attr_value_t
string = SIM_make_attr_string(
78 SIM_attr_list_set_item(&ret, 1,
string);
82 return SIM_make_attr_nil();
90 if (SIM_attr_is_list(src)) {
91 if (SIM_attr_list_size(src) != 2) {
93 "Expected Simics list type with exactly 2 members"
97 auto item = SIM_attr_list_item(src, 0);
98 if (!SIM_attr_is_object(item)) {
100 "The first item should be Simics object type"
105 item = SIM_attr_list_item(src, 1);
106 if (!SIM_attr_is_string(item)) {
108 "The second item should be Simics string type"
114 if (!SIM_attr_is_object(src) && !SIM_attr_is_nil(src)) {
116 "Expected Simics object or NIL type"
119 return SIM_attr_object_or_nil(src);
127 static constexpr bool value = std::is_base_of<ConnectBase, T>::value
128 && std::is_constructible<T, const ConfObjectRef &>::value;
136template <
typename T,
typename Alloc>
140template <
typename T,
typename Alloc>
144template <
typename T,
typename Alloc>
153template <
typename T, std::
size_t N>
155 : std::is_base_of<ConnectBase, T> {};
161template <
typename T>
inline
162typename std::enable_if<std::is_enum<T>::value, attr_value_t>::type
165 static_cast<std::underlying_type_t<T>
>(src));
171template <
typename T>
inline
172typename std::enable_if<std::is_base_of<ConnectBase, T>::value,
181template <
typename T>
inline
182typename std::enable_if<std::is_pointer<T>::value, attr_value_t>::type
185 static_assert(std::is_same<T, const char *>::value,
186 "Pointer type is not allowed due to not checkpointable");
193template <
typename T>
inline
194typename std::enable_if<!std::is_enum<T>::value
195 && !std::is_base_of<ConnectBase, T>::value
196 && !std::is_pointer<T>::value,
205template <
typename T>
inline
206typename std::enable_if<std::is_enum<T>::value, T>::type
208 return static_cast<T
>(
215template <
typename T>
inline
216typename std::enable_if<std::is_base_of<ConnectBase, T>::value, T>::type
220 throw std::runtime_error {
221 "Unable to set to an illegal object"
230template <
typename T>
inline
231typename std::enable_if<std::is_pointer<T>::value, T>::type
234 static_assert(std::is_same<T, const char *>::value,
235 "Pointer type is not allowed due to not checkpointable");
242template <
typename T>
inline
243typename std::enable_if<!std::is_enum<T>::value
244 && !std::is_base_of<ConnectBase, T>::value
245 && !std::is_pointer<T>::value, T>::type
253#define _STD2ATTR_INT_HELPER(type) \
255 struct attr_from_std_helper<type> { \
256 static attr_value_t f(const type &src) { \
257 return SIM_make_attr_int64(src); \
260#define _STD2ATTR_UINT_HELPER(type) \
262 struct attr_from_std_helper<type> { \
263 static attr_value_t f(const type &src) { \
264 return SIM_make_attr_uint64(src); \
278#undef _STD2ATTR_INT_HELPER
279#undef _STD2ATTR_UINT_HELPER
281#define _ATTR2STD_INT_HELPER(type) \
283 struct attr_to_std_helper<type> { \
284 static type f(const attr_value_t &src) { \
285 if (!SIM_attr_is_integer(src)) { \
286 throw SetIllegalType { \
287 "Expected Simics integer type" \
290 intmax_t i = SIM_attr_integer(src); \
291 if (sizeof(type) != 8 \
292 && (i > (std::numeric_limits<type>::max)() \
293 || i < (std::numeric_limits<type>::min)())) { \
294 throw SetIllegalValue { \
295 "Value does not fit in type" \
302#define _ATTR2STD_UINT_HELPER(type) \
304 struct attr_to_std_helper<type> { \
305 static type f(const attr_value_t &src) { \
306 if (!SIM_attr_is_integer(src)) { \
307 throw SetIllegalType { \
308 "Expected Simics integer type" \
311 uintmax_t i = static_cast<uintmax_t>( \
312 SIM_attr_integer(src)); \
313 if (sizeof(type) != 8 \
314 && i > (std::numeric_limits<type>::max)()) { \
315 throw SetIllegalValue { \
316 "Value does not fit in type" \
333#undef _ATTR2STD_INT_HELPER
334#undef _ATTR2STD_UINT_HELPER
338#define _STD2ATTR_FLOAT_HELPER(type) \
340 struct attr_from_std_helper<type> { \
341 static attr_value_t f(const type &src) { \
342 return SIM_make_attr_floating(src); \
347#undef _STD2ATTR_FLOAT_HELPER
349#define _ATTR2STD_FLOAT_HELPER(type) \
351 struct attr_to_std_helper<type> { \
352 static type f(const attr_value_t &src) { \
353 if (!SIM_attr_is_floating(src)) { \
354 throw SetIllegalType { \
355 "Expected Simics floating type" \
358 return (type) SIM_attr_floating(src); \
363#undef _ATTR2STD_FLOAT_HELPER
369 static attr_value_t
f(
const std::string &src) {
370 return SIM_make_attr_string(src.c_str());
376 static std::string
f(
const attr_value_t &src) {
377 if (!SIM_attr_is_string(src)) {
379 "Expected Simics string type"
382 return SIM_attr_string(src);
388 static attr_value_t
f(
const char *src) {
389 return SIM_make_attr_string(src);
395 static const char *
f(
const attr_value_t &src) {
396 if (SIM_attr_is_nil(src)) {
399 if (!SIM_attr_is_string(src)) {
401 "Expected Simics string type"
404 return SIM_attr_string(src);
413 static attr_value_t
f(
const bool &src) {
414 return SIM_make_attr_boolean(src);
420 static bool f(
const attr_value_t &src) {
421 if (!SIM_attr_is_boolean(src)) {
423 "Expected Simics boolean type"
426 return SIM_attr_boolean(src);
434 static attr_value_t
f(
const attr_value_t &src) {
441 static attr_value_t
f(
const attr_value_t &src) {
448template <
typename C,
typename T =
typename C::value_type>
450 const auto size = src.size();
452 const unsigned size_uint =
static_cast<unsigned>(size);
453 attr_value_t dst = SIM_alloc_attr_list(size_uint);
454 auto it = src.cbegin();
455 for (
unsigned i = 0; i < size_uint; ++i, ++it) {
461template <
typename V, std::
size_t N>
463 static attr_value_t
f(
const std::array<V, N> &src) {
464 return from_container<std::array<V, N>>(src);
468template <
typename V, std::
size_t N>
470 static attr_value_t
f(
const V (&src)[N]) {
471 std::array<V, N> std_arr;
472 for (std::size_t i = 0; i < N; ++i) {
475 return from_container<std::array<V, N>>(std_arr);
479template <std::
size_t N>
481 static attr_value_t
f(
const char (&src)[N]) {
482 return SIM_make_attr_string(src);
488 static attr_value_t
f(
const std::vector<V> &src) {
489 return from_container<std::vector<V>>(src);
495 static attr_value_t
f(
const std::list<V> &src) {
496 return from_container<std::list<V>>(src);
502 static attr_value_t
f(
const std::deque<V> &src) {
503 return from_container<std::deque<V>>(src);
509 static attr_value_t
f(
const std::set<V> &src) {
510 return from_container<std::set<V>>(src);
514template <
typename X,
typename Y>
516 static attr_value_t
f(
const std::pair<X, Y>& src) {
517 attr_value_t dst = SIM_alloc_attr_list(2);
518 SIM_attr_list_set_item(&dst, 0,
std_to_attr(src.first));
519 SIM_attr_list_set_item(&dst, 1,
std_to_attr(src.second));
524template <
typename X,
typename Y>
526 static attr_value_t
f(
const std::map<X, Y>& src) {
527 const auto size = src.size();
529 attr_value_t dst = SIM_alloc_attr_list(
static_cast<unsigned>(size));
531 for (
const auto &p : src) {
532 SIM_attr_list_set_item(&dst, index++,
534 p.first, p.second)));
540template <
typename... Args>
542 static attr_value_t
f(
const std::tuple<Args...> &src) {
543 attr_value_t dst = SIM_alloc_attr_list(
sizeof...(Args));
544 set_items(&dst, src, 0, std::index_sequence_for<Args...>());
550 template<std::size_t Index, std::size_t... Is>
551 static void set_items(attr_value_t *dst,
const std::tuple<Args...> &src,
552 std::size_t current_index,
553 std::index_sequence<Index, Is...>) {
554 SIM_attr_list_set_item(dst, Index,
std_to_attr(std::get<Index>(src)));
555 set_items(dst, src, current_index + 1, std::index_sequence<Is...>());
559 static void set_items(attr_value_t *,
const std::tuple<Args...> &,
560 std::size_t, std::index_sequence<>) {}
563template <
typename C,
typename T =
typename C::value_type>
565 if (!SIM_attr_is_list(src)) {
567 "Expected Simics list type"
570 const unsigned size = SIM_attr_list_size(src);
572 for (
unsigned i = 0; i < size; ++i) {
573 v.push_back(attr_to_std<T>(SIM_attr_list_item(src, i)));
575 return {v.begin(), v.end()};
580 static std::vector<V>
f(
const attr_value_t &src) {
581 return to_container<std::vector<V>>(src);
587 static std::list<V>
f(
const attr_value_t &src) {
588 return to_container<std::list<V>>(src);
594 static std::deque<V>
f(
const attr_value_t &src) {
595 return to_container<std::deque<V>>(src);
601 static std::set<V>
f(
const attr_value_t &src) {
602 return to_container<std::set<V>>(src);
606template <
typename V, std::
size_t N>
608 static std::array<V, N>
f(
const attr_value_t &src) {
609 if (!SIM_attr_is_list(src)) {
611 "Expected Simics list type"
614 const unsigned size = SIM_attr_list_size(src);
617 "Size mismatch for std::array"
620 std::array<V, N> result;
621 for (
unsigned i = 0; i < size; ++i) {
622 result[i] = attr_to_std<V>(SIM_attr_list_item(src, i));
628template <
typename X,
typename Y>
630 static std::pair<X, Y>
f(
const attr_value_t& src) {
631 if (!SIM_attr_is_list(src) || SIM_attr_list_size(src) != 2) {
633 "Expected Simics list type with exactly two members"
636 return {attr_to_std<X>(SIM_attr_list_item(src, 0)),
637 attr_to_std<Y>(SIM_attr_list_item(src, 1))};
641template <
typename X,
typename Y>
643 static std::map<X, Y>
f(
const attr_value_t& src) {
644 if (!SIM_attr_is_list(src)) {
646 "Expected Simics list type"
650 for (
unsigned i = 0; i < SIM_attr_list_size(src); ++i) {
652 SIM_attr_list_item(src, i)));
658template <
typename... Args>
660 static std::tuple<Args...>
f(
const attr_value_t &src) {
661 if (!SIM_attr_is_list(src)
662 || SIM_attr_list_size(src) !=
sizeof...(Args)) {
664 "Expected Simics list type with exactly " + \
665 std::to_string(
sizeof...(Args)) +
" members"
669 return convert_tuple(src, std::index_sequence_for<Args...>());
674 template<std::size_t... Is>
675 static std::tuple<Args...> convert_tuple(
const attr_value_t &src,
676 std::index_sequence<Is...>) {
677 return std::make_tuple(convert_item<Args>(src, Is)...);
681 static T convert_item(
const attr_value_t &src, std::size_t index) {
682 return attr_to_std<T>(SIM_attr_list_item(src, index));
692 const auto size = src.size();
694 return SIM_make_attr_data(size, src.data());
701 if (!SIM_attr_is_data(src)) {
703 "Expected Simics data type"
706 size_t size = SIM_attr_data_size(src);
707 const uint8 *data = SIM_attr_data(src);
#define _STD2ATTR_UINT_HELPER(type)
Definition: attribute-traits.h:260
#define _ATTR2STD_UINT_HELPER(type)
Definition: attribute-traits.h:302
#define _STD2ATTR_INT_HELPER(type)
Definition: attribute-traits.h:253
#define _ATTR2STD_FLOAT_HELPER(type)
Definition: attribute-traits.h:349
#define _ATTR2STD_INT_HELPER(type)
Definition: attribute-traits.h:281
#define _STD2ATTR_FLOAT_HELPER(type)
Definition: attribute-traits.h:338
Represents Simics C type conf_object_t.
Definition: conf-object.h:38
const std::string & port_name() const
Get & set name for the port implements the interface.
Definition: conf-object.h:60
void set_port_name(const std::string &name)
Definition: conf-object.h:61
Definition: attribute-exceptions.h:38
Definition: attribute-exceptions.h:51
std::vector< uint8 > data_attribute
Definition: attribute-traits.h:687
C to_container(const attr_value_t &src)
Definition: attribute-traits.h:564
attr_value_t from_container(const C &src)
Definition: attribute-traits.h:449
Definition: after-bank.h:33
void checkSizeOverflowSimicsAttribute(size_t size)
The maximum supported size for a Simics attribute dictionary/list/data is 2**32-1 bytes.
Definition: attribute-traits.h:40
std::enable_if< std::is_enum< T >::value, attr_value_t >::type std_to_attr(const T &src)
Function transforms C++ enum type T to Simics attr_value_t.
Definition: attribute-traits.h:163
std::enable_if< std::is_enum< T >::value, T >::type attr_to_std(attr_value_t src)
Function transforms Simics attr_value_t to C++ enum type.
Definition: attribute-traits.h:207
Definition: common-types.h:66
static attr_value_t f(const ConfObjectRef &src)
Definition: attribute-traits.h:69
static attr_value_t f(const V(&src)[N])
Definition: attribute-traits.h:470
static attr_value_t f(const attr_value_t &src)
Definition: attribute-traits.h:434
static attr_value_t f(const bool &src)
Definition: attribute-traits.h:413
static attr_value_t f(const char(&src)[N])
Definition: attribute-traits.h:481
static attr_value_t f(const char *src)
Definition: attribute-traits.h:388
static attr_value_t f(const data_attribute &src)
Definition: attribute-traits.h:691
static attr_value_t f(const std::array< V, N > &src)
Definition: attribute-traits.h:463
static attr_value_t f(const std::deque< V > &src)
Definition: attribute-traits.h:502
static attr_value_t f(const std::list< V > &src)
Definition: attribute-traits.h:495
static attr_value_t f(const std::map< X, Y > &src)
Definition: attribute-traits.h:526
static attr_value_t f(const std::pair< X, Y > &src)
Definition: attribute-traits.h:516
static attr_value_t f(const std::set< V > &src)
Definition: attribute-traits.h:509
static attr_value_t f(const std::string &src)
Definition: attribute-traits.h:369
static attr_value_t f(const std::tuple< Args... > &src)
Definition: attribute-traits.h:542
static attr_value_t f(const std::vector< V > &src)
Definition: attribute-traits.h:488
Definition: attribute-traits.h:51
static attr_value_t f(const T &src)
static ConfObjectRef f(const attr_value_t &src)
Definition: attribute-traits.h:89
static attr_value_t f(const attr_value_t &src)
Definition: attribute-traits.h:441
static bool f(const attr_value_t &src)
Definition: attribute-traits.h:420
static const char * f(const attr_value_t &src)
Definition: attribute-traits.h:395
static data_attribute f(const attr_value_t &src)
Definition: attribute-traits.h:700
static std::array< V, N > f(const attr_value_t &src)
Definition: attribute-traits.h:608
static std::deque< V > f(const attr_value_t &src)
Definition: attribute-traits.h:594
static std::list< V > f(const attr_value_t &src)
Definition: attribute-traits.h:587
static std::map< X, Y > f(const attr_value_t &src)
Definition: attribute-traits.h:643
static std::pair< X, Y > f(const attr_value_t &src)
Definition: attribute-traits.h:630
static std::set< V > f(const attr_value_t &src)
Definition: attribute-traits.h:601
static std::string f(const attr_value_t &src)
Definition: attribute-traits.h:376
static std::tuple< Args... > f(const attr_value_t &src)
Definition: attribute-traits.h:660
static std::vector< V > f(const attr_value_t &src)
Definition: attribute-traits.h:580
Definition: attribute-traits.h:59
static T f(const attr_value_t &src)
Definition: attribute-traits.h:125
static constexpr bool value
Definition: attribute-traits.h:127
Definition: attribute-traits.h:151
Definition: attribute-traits.h:134